Variables
Goals
- Understand variables and variable scope.
- Declare, initialize, and modify variables.
- Make variables unchangeable.
Concepts
- assignment
- binary
- bit
- byte
- block
- declare
- expression
- foobar
- initialize
- integer
- literal
- nested
- scope
- statement
- type
- variable
Language
byte
final
int
Preview
final int cowCount = 4;
final int length = 2;
final int width = 3;
final int area = length * width;
Lesson
On another day you are driving down the same country road where in a previous lesson you saw the four cows in the field. You seem to remember there were four of them; you had even written down the digit “4” in your notebook. You wonder if if anyone has ever studied the relationship between the number of cows and the size of the field.
You decide to note the number of cows, the length of the field, the width of the field, and the total area. You stop the car and make a rough estimate:
- cow count
- 4
- field length
- 2
- field width
- 3
- area
- 6 (2 × 3)
There is little chance you'll remember those numbers by the time you return home, so you look around for your trusty notepad. Of all things: today you not only forgot to charge your phone, you also left your notepad at home! All you can find in the car are some old linen sheets and a can of paint left over from the remodeling job you're doing back home.
You gaze toward the fence posts; they remind you of something, but you can't put your finger on it… ah, the lesson about base two representation, or binary. Base two uses 0
and 1
to represent values: the digit “4” in base 10 and the number 100
in binary are simply different representations of the same value.
In a flash of inspiration you grab the sheets and the leftover paint. Each fence post could represent a binary 0
or 1
; you could paint a fence post to represent 1
, or leave it unpainted to represent 0
. There are many fence posts, so you mark them off in groups of three with the sheets, scrawling out a descriptive name on each. Here is what you end up with:
- cow count
1 0 0
- field length
0 1 0
- field width
0 1 1
- area
1 1 0
Using the fence posts as binary representations, you've noted several values that, for those who understand binary, are as clear and unambiguous as if you had written “4”, “2”, “3”, and “6” on a notepad. As long as the wind doesn't blow the sheets down, your calculated values will still be recorded there the next day when you return.
Variables
The data stored inside your electronic gadgets are little more than than millions of tiny fence posts, each referred to as a bit and “painted” with electricity to represent 0
or 1
. A software developer will mark off groups of these bits and give each group a name, just as you might have done by hanging sheets on fence posts. In a computer program each named group of bits is called a variable. The word “variable” implies you can later change its value—just as you could repaint fence posts without changing the words written on the banner hanging in front of them.
Each variable in Java is given a type which indicates how many bits it will use, as well as how those bits will be interpreted. You already know that a byte represents eight bits of information, and in Java the type indicating eight bits is indeed called byte
. Just as you marked off three fence posts and put a name on a banner in front of them, you can use the byte
type with a name to tell Java to mark off eight bits and effectively “hang a banner” on them with the name you give. This is referred to as declaring a variable.
Of course you probably want to tell Java what pattern to “paint the fence posts” behind this cowCount
banner, so when you declare the variable you can also initialize it with a value. The equals =
symbol is used to represent a variable assignment.
Remember when you told Java to print the words "Hello, world!" in a previous lesson? In the same way you can tell Java to print a variable, and Java will print a number indicating the value the variable represents.
Types
At the beginning of this lesson you used three fence posts as bits to represent the number of cows in a field. If all three bits are turned “on”, 1 1 1
, the highest highest value three bits can represent is thus 0b111
in binary, which is 7
in decimal. The Java byte
type you have been using so far uses eight bits, which can store values higher than 7
but is still limited; many values a programmer encounters from day to day are much longer than can be stored in a byte
.
A type that is much more useful in Java is int
, which represents an integer or whole number. An int
functions identically to a byte
, except that it uses 32 bits instead of eight, allowing an int
to store most values a programmer will encounter in a typical programming task. Moreover most computers process numbers internally using many more bits than contained in a single byte, so there is usually little benefit to choosing the small byte
type. For this reason int
is the type developers usually use when dealing with integer values.
Expressions
When you initialize a variable you can use a mathematical expression including such things as addition, subtraction, multiplication, and division. You can include literal values and even other variables!
You can later change the value of a variable after you have declared it.
If you don't want a variable's value to be changed, you can use the keyword final
, which makes the value read-only:
Scope
In the original “Hello, World!” program you saw that both the class HelloWorld
and the method main()
had a matching pair of braces: { }
, with the first pair enclosing the second pair. When a pair of braces occurs inside another pair of braces, we say the two pairs are nested, like a set of Russian matryoshka dolls.
Each matching pair of braces (called a block) creates a new variable scope. Scope refers both to how long a variable lives and how it can be seen by other lines in the program. Here is how it works:
- You can define new variables inside a nested scope.
- Normally new variables inside the nested (child) scope cannot have the same name as variables in the outer (parent) scope.
- Statements in the parent scope cannot access anything inside the child scope.
- Statements in the child scope can see everything in the parent scope.
- At the end of any scope (i.e. when the ending brace is reached) all the variables within that scope (defined within that block) disappear. Poof!
Let's see how that would work using three variable named x
, y
, and z
.
You can always create a new scope simply by adding another nested pair of brackets. In fact sometimes this is even useful, if you want to make a temporary calculation and then throw away the intermediate variables used in the calculation, to prevent yourself from accidentally using those intermediate values. But usually scopes are created by merely using existing Java constructs. A method, for example, creates a separate scope that is not connected with the scopes of the other methods in the same class.
Review
Summary
Gotchas
- Don't forget the semicolon at the end of each statement!
- Because Java uses the
int
type internally by default in expressions, attempting to assign an expression to abyte
will produce an error, even if the expression contains onlybyte
values. - You can change the value of a variable, but doing so won't change the values of other variables that might have already used this variable in an expression.
- You cannot normally create a variable in a child scope with the same name as a variable in a parent scope.
In the Real World
- You, the developer, are your own worst enemy! Do everything possible to prevent yourself from making errors!
- Use meaningful variable names. Only use single-letter variables in certain circumstances where they are expected, such as
i
for loops (andj
for a nested loop). - Use
final
as much as possible! You can (almost) never use it too much. While this is somewhat a matter of taste, you can't go wrong by assuming a variable will never be changed and making itfinal
by default. If you later really need to change the value, you can remove thefinal
later, but mutable variables should be the exception, not the rule. About the only place it doesn't make sense is in interface definitions, asfinal
is an implementation detail, but even then it won't hurt anything. - The
int
type is the most common type to represent integer values. Don't use a smaller type such asbyte
unless you have a particular reason to do so.
Self Evaluation
- What is the difference between a literal and a variable?
- How many bits does the
byte
type use to store a value? - What type does Java use internally by default for literal integer values?
- What is scope? Can a variable in a child scope have the same variable as that in a parent scope?
- How long is the life of a variable?
Task
Create a program that solves the following problems, printing out the answers. Do not use loops (even if you know what that is), and use as few literals as possible. Before printing out each value, it would be helpful to the user to print out a label indicating what the value represents.
- What are the first 10 even integers?
- If
17
people are in a room and5
of them leave, how many are left?
Continue using the same base package name for this task and for those in the upcoming lessons. Create a compressed archive of your entire project directory and send it to your teacher.
See Also
References
Acknowledgments
- Cow Variables cartoon drawn by Jason J. Patterson.
- Matryoshka doll photo by Fanghong, [CC BY-SA 3.0], via Wikimedia Commons.