Chapter 4
Making the Most of Variables and Their Values
In This Chapter
Assigning values to things
Making things store certain types of values
Applying operators to get new values
The following conversation between Mr. Van Doren and Mr. Barasch never took place:
Charles: A sea squirt eats its brain, turning itself from an animal into a plant.
Jack: Is that your final answer, Charles?
Charles: Yes, it is.
Jack: How much money do you have in your account today, Charles?
Charles: I have fifty dollars and twenty-two cents in my checking account.
Jack: Well, you better call the IRS, because your sea squirt answer is correct. You just won a million dollars to add to your checking account. What do you think of that, Charles?
Charles: I owe it all to honesty, diligence, and hard work, Jack.
Some aspects of this dialogue can be represented in Java by a few lines of code.
Varying a Variable
No matter how you acquire your million dollars, you can use a variable to tally your wealth. Listing 4-1 shows the code.
Listing 4-1: Using a Variable
amountInAccount = 50.22;
amountInAccount = amountInAccount + 1000000.00;
The code in Listing 4-1 makes use of the amountInAccount
variable. A variable is a placeholder. You can stick a number like 50.22 into a variable. After you place a number in the variable, you can change your mind and put a different number into the variable. (That’s what varies in a variable.) Of course, when you put a new number in a variable, the old number is no longer there. If you didn’t save the old number somewhere else, the old number is gone.
Figure 4-1 gives a before-and-after picture of the code in Listing 4-1. After the first statement in Listing 4-1 is executed, the variable amountInAccount
has the number 50.22 in it. Then, after the second statement of Listing 4-1 is executed, the amountInAccount
variable suddenly has 1000050.22 in it. When you think about a variable, picture a place in the computer’s memory where wires and transistors store 50.22, 1000050.22, or whatever. In the left side of Figure 4-1, imagine that the box with 50.22 in it is surrounded by millions of other such boxes.
Now you need some terminology. The thing stored in a variable is a value. A variable’s value can change during the run of a program (when Jack gives you a million bucks, for instance). The value that’s stored in a variable isn’t necessarily a number. (For instance, you can create a variable that always stores a letter.) The kind of value that’s stored in a variable is a variable’s type.
You can read more about types in the section “Understanding the Types of Values That Variables May Have,” later in this chapter.
Every variable name is an identifier — a name that you can make up in your own code. In preparing Listing 4-1, I made up the name amountInAccount.
Before the sun sets on Listing 4-1, you need to notice one more part of the listing. The listing has 50.22
and 1000000.00
in it. Anybody in his or her right mind would call these things numbers, but in a Java program it helps to call these things literals.
And what’s so literal about 50.22
and 1000000.00
? Well, think about the variable amountInAccount
in Listing 4-1. The variable amountInAccount
stands for 50.22 some of the time, but it stands for 1000050.22 the rest of the time. You could use the word number to talk about amountInAccount
. But really, what amountInAccount
stands for depends on the fashion of the moment. On the other hand, 50.22
literally stands for the value 5022⁄100.
Assignment Statements
Statements like the ones in Listing 4-1 are called assignment statements. In an assignment statement, you assign a value to something. In many cases, this something is a variable.
I recommend getting into the habit of reading assignment statements from right to left. Figure 4-2 illustrates the action of the first line in Listing 4-1.
The second line in Listing 4-1 is just a bit more complicated. Figure 4-3 illustrates the action of the second line in Listing 4-1.
Understanding the Types of Values That Variables May Have
Have you seen the TV commercials that make you think you’re flying around among the circuits inside a computer? Pretty cool, eh? These commercials show 0s (zeros) and 1s sailing by because 0s and 1s are the only things that computers can really deal with. When you think a computer is storing the letter J, the computer is really storing 01001010. Everything inside the computer is a sequence of 0s and 1s. As every computer geek knows, a 0 or 1 is called a bit.
As it turns out, the sequence 01001010, which stands for the letter J, can also stand for the number 74. The same sequence can also stand for 1.0369608636003646 × 10–43. In fact, if the bits are interpreted as screen pixels, the same sequence can be used to represent the dots shown in Figure 4-4. The meaning of 01001010 depends on the way the software interprets this sequence of 0s and 1s.
So how do you tell the computer what 01001010 stands for? The answer is in the concept of type. The type of a variable is the range of values that the variable is permitted to store.
I copied the lines from Listing 4-1 and put them into a complete Java program. The program is in Listing 4-2. When I run the program in Listing 4-2, I get the output shown in Figure 4-5.
Listing 4-2: A Program Uses amountInAccount
class Millionaire {
public static void main(String args[]) {
double amountInAccount;
amountInAccount = 50.22;
amountInAccount = amountInAccount + 1000000.00;
System.out.print(“You have $”);
System.out.print(amountInAccount);
System.out.println(“ in your account.”);
}
}
In Listing 4-2, look at the first line in the body of the main
method.
double amountInAccount;
This line is called a variable declaration. Putting this line in your program is like saying, “I’m declaring my intention to have a variable named amountIn-Account in my program.” This line reserves the name amountInAccount for your use in the program.
In this variable declaration, the word double is a Java keyword. This word double tells the computer what kinds of values you intend to store in amountInAccount
. In particular, the word double stands for numbers between –1.8 × 10308 and 1.8 × 10308. (These are enormous numbers with 308 zeros before the decimal point. Only the world’s richest people write checks with 308 zeros in them. The second of these numbers is one-point-eight gazazzo-zillion-kaskillion. The number 1.8 × 10308, a constant defined by the International Bureau of Weights and Measures, is the number of eccentric computer programmers between Sunnyvale, California, and the M31 Andromeda Galaxy.)
More important than the humongous range of the double
keyword’s numbers is the fact that a double
value can have digits beyond the decimal point. After you declare amountInAccount
to be of type double
, you can store all sorts of numbers in amountInAccount
. You can store 50.22, 0.02398479, or –3.0. In Listing 4-2, if I hadn’t declared amountInAccount
to be of type double
, I may not have been able to store 50.22. Instead, I would have had to store plain old 50, without any digits beyond the decimal point.
Another type — type float
— also allows you to have numbers after the decimal point, but this type isn’t as accurate. (See the sidebar, “Digits beyond the decimal point,” for the full story.) Don’t sweat the choice between float
and double
. For most programs, just use double
.
Displaying Text
The last three statements in Listing 4-2 use a neat formatting trick. You want to display several different things on a single line on the screen. You put these things in separate statements. All but the last of the statements are calls to System.out.print
. (The last statement is a call to System.out.println
.) Calls to System.out.print
display text on part of a line and then leave the cursor at the end of the current line. After executing System.out.print
, the cursor is still at the end of the same line, so the next System.out.
whatever
can continue printing on that same line. With several calls to print capped off by a single call to println
, the result is just one nice-looking line of output. (Refer to Figure 4-5.)
Numbers without Decimal Points
“In 1995, the average family had 2.3 children.”
At this point, a wise guy always remarks that no real family has exactly 2.3 children. Clearly, whole numbers have a role in this world. Therefore, in Java, you can declare a variable to store nothing but whole numbers. Listing 4-3 shows a program that uses whole number variables.
Listing 4-3: Using the int Type
class ElevatorFitter {
public static void main(String args[]) {
int weightOfAPerson;
int elevatorWeightLimit;
int numberOfPeople;
weightOfAPerson = 150;
elevatorWeightLimit = 1400;
numberOfPeople =
elevatorWeightLimit / weightOfAPerson;
System.out.print(“You can fit “);
System.out.print(numberOfPeople);
System.out.println(“ people on the elevator.”);
}
}
The story behind the program in Listing 4-3 takes some heavy-duty explaining. So here goes:
You have a hotel elevator whose weight capacity is 1,400 pounds. One weekend, the hotel hosts the Brickenchicker family reunion. A certain branch of the Brickenchicker family has been blessed with identical dectuplets (ten siblings, all with the same physical characteristics). Normally, each of the Brickenchicker dectuplets weighs exactly 145 pounds. But on Saturday, the family has a big catered lunch, and, because lunch included strawberry shortcake, each of the Brickenchicker dectuplets now weighs 150 pounds. Immediately after lunch, all ten of the Brickenchicker dectuplets arrive at the elevator at exactly the same time. (Why not? All ten of them think alike.) So, the question is, how many of the dectuplets can fit on the elevator?
Now remember, if you put one ounce more than 1,400 pounds of weight on the elevator, the elevator cable breaks, plunging all dectuplets on the elevator to their sudden (and costly) deaths.
The answer to the Brickenchicker riddle (the output of the program of Listing 4-3) is shown in Figure 4-6.
At the core of the Brickenchicker elevator problem, you have whole numbers — numbers with no digits beyond the decimal point. When you divide 1,400 by 150, you get 91⁄3, but you shouldn’t take the 1⁄3 seriously. No matter how hard you try, you can’t squeeze an extra 50 pounds worth of Brickenchicker dectuplet onto the elevator. This fact is reflected nicely in Java. In Listing 4-3, all three variables (weightOfAPerson
, elevatorWeightLimit
, and numberOfPeople
) are of type int
. An int
value is a whole number. When you divide one int
value by another (as you do with the slash in Listing 4-3), you get another int
. When you divide 1,400 by 150, you get 9 — not 91⁄3. You see this in Figure 4-6. Taken together, the following statements display 9 onscreen:
numberOfPeople =
elevatorWeightLimit / weightOfAPerson;
System.out.print(numberOfPeople);
Combining Declarations and Initializing Variables
Look back at Listing 4-3. In that listing, you see three variable declarations — one for each of the program’s three int
variables. I could have done the same thing with just one declaration:
int weightOfAPerson, elevatorWeightLimit, numberOfPeople;
You can give variables their starting values in a declaration. In Listing 4-3 for instance, one declaration can replace several lines in the main
method (all but the calls to print
and println
).
int weightOfAPerson = 150, elevatorWeightLimit = 1400,
numberOfPeople = elevatorWeightLimit/weightOfAPerson;
When you do this, you don’t say that you’re assigning values to variables. The pieces of the declarations with equal signs in them aren’t really called assignment statements. Instead, you say that you’re initializing the variables. Believe it or not, keeping this distinction in mind is helpful.
Like everything else in life, initializing a variable has advantages and disadvantages:
When you combine six lines of Listing 4-3 into just one declaration, the code becomes more concise. Sometimes, concise code is easier to read. Sometimes it’s not. As a programmer, it’s your judgment call.
By initializing a variable, you might automatically avoid certain programming errors. For an example, see Chapter 7.
In some situations, you have no choice. The nature of your code forces you either to initialize or not to initialize. For an example that doesn’t lend itself to variable initialization, see the deleting-evidence program in Chapter 6.
The Atoms: Java’s Primitive Types
The words int and double that I describe in the previous sections are examples of primitive types (also known as simple types) in Java. The Java language has exactly eight primitive types. As a newcomer to Java, you can pretty much ignore all but four of these types. (As programming languages go, Java is nice and compact that way.) Table 4-1 shows the complete list of primitive types.
Table 4-1 Java’s Primitive Types
Type Name |
What a Literal Looks Like |
Range of Values |
Whole number types |
||
|
|
–128 to 127 |
|
|
–32768 to 32767 |
|
|
–2147483648 to 2147483647 |
|
|
–9223372036854775808 to 9223372036854775807 |
Decimal number types |
||
|
|
–3.4 × 1038 to 3.4 × 1038 |
|
|
–1.8 × 10308 to 1.8 × 10308 |
Character type |
||
|
|
Thousands of characters, glyphs, and symbols |
Logical type |
||
|
|
true, false |
The types that you shouldn’t ignore are int
, double
, char
, and boolean
. Previous sections in this chapter cover the int
and double
types. So, this section covers char
and boolean
types.
The char type
Not so long ago, people thought computers existed only for doing big number-crunching calculations. Nowadays, with word processors, nobody thinks that way anymore. So, if you haven’t been in a cryogenic freezing chamber for the last 20 years, you know that computers store letters, punctuation symbols, and other characters.
The Java type that’s used to store characters is called char. Listing 4-4 has a simple program that uses the char
type. Figure 4-7 shows the output of the program in Listing 4-4.
Listing 4-4: Using the char Type
class CharDemo {
public static void main(String args[]) {
char myLittleChar = ‘b’;
char myBigChar = Character.toUpperCase(myLittleChar);
System.out.println(myBigChar);
}
}
In Listing 4-4, the first initialization stores the letter b in the variable myLittleChar
. In the initialization, notice how b is surrounded by single quote marks. In Java, every char
literal starts and ends with a single quote mark.
If you need help sorting out the terms assignment, declaration, and initialization, see the “Combining Declarations and Initializing Variables” section, earlier in this chapter.
In the second initialization of Listing 4-4, the program calls an API method whose name is Character.toUpperCase. The Character.toUpperCase
method does just what its name suggests — the method produces the uppercase equivalent of the letter b. This uppercase equivalent (the letter B) is assigned to the myBigChar
variable, and the B that’s in myBigChar
prints onscreen.
If you’re tempted to write the following statement,
char myLittleChars = ‘barry’; //Don’t do this
please resist the temptation. You can’t store more than one letter at a time in a char
variable, and you can’t put more than one letter between a pair of single quotes. If you’re trying to store words or sentences (not just single letters), you need to use something called a String.
For a look at Java’s String
type, see the section, “The Molecules and Compounds: Reference Types,” later in this chapter.
It’s worth noticing that the two methods, Character.toUpperCase
and System.out.println
, are used quite differently in Listing 4-4. The method Character.toUpperCase
is called as part of an initialization or an assignment statement, but the method System.out.println
is called on its own. To find out more about this, see Chapter 7.
The boolean type
A variable of type boolean
stores one of two values — true
or false
. Listing 4-5 demonstrates the use of a boolean
variable. Figure 4-8 shows the output of the program in Listing 4-5.
Listing 4-5: Using the boolean Type
class ElevatorFitter2 {
public static void main(String args[]) {
System.out.println(“True or False?”);
System.out.println(“You can fit all ten of the”);
System.out.println(“Brickenchicker dectuplets”);
System.out.println(“on the elevator:”);
System.out.println();
int weightOfAPerson = 150;
int elevatorWeightLimit = 1400;
int numberOfPeople =
elevatorWeightLimit / weightOfAPerson;
boolean allTenOkay = numberOfPeople >= 10;
System.out.println(allTenOkay);
}
}
In Listing 4-5, the allTenOkay
variable is of type boolean
. To find a value for the allTenOkay
variable, the program checks to see whether numberOfPeople
is greater than or equal to ten. (The symbols >=
stand for greater than or equal to.)
At this point, it pays to be fussy about terminology. Any part of a Java program that has a value is an expression. If you write
weightOfAPerson = 150;
then 150
is an expression (an expression whose value is the quantity 150
). If you write
numberOfEggs = 2 + 2;
then 2 + 2
is an expression (because 2 + 2 has the value 4
). If you write
int numberOfPeople =
elevatorWeightLimit / weightOfAPerson;
then elevatorWeightLimit / weightOfAPerson
is an expression. (The value of the expression elevatorWeightLimit / weightOfAPerson
depends on whatever values the variables elevatorWeightLimit
and weightOfAPerson
have when the code containing the expression is executed.)
In Listing 4-5, the code numberOfPeople >= 10
is an expression. The expression’s value depends on the value stored in the numberOfPeople
variable. But, as you know from seeing the strawberry shortcake at the Brickenchicker family’s catered lunch, the value of numberOfPeople
isn’t greater than or equal to ten. This makes the value of numberOfPeople >= 10
to be false
. So, in the statement in Listing 4-5, in which allTenOkay
is assigned a value, the allTenOkay
variable is assigned a false
value.
The Molecules and Compounds: Reference Types
By combining simple things, you get more complicated things. That’s the way it always goes. Take some of Java’s primitive types, whip them together to make a primitive type stew, and what do you get? A more complicated type called a reference type.
The program in Listing 4-6 uses reference types. Figure 4-9 shows you what happens when you run the program in Listing 4-6.
Listing 4-6: Using Reference Types
import javax.swing.JFrame;
class ShowAFrame {
public static void main(String args[]) {
JFrame myFrame = new JFrame();
String myTitle = “Blank Frame”;
myFrame.setTitle(myTitle);
myFrame.setSize(300, 200);
myFrame.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
}
The program in Listing 4-6 uses two references types. Both types are defined in the Java API. One of the types (the one that you’ll use all the time) is called String. The other type (the one that you can use to create GUIs) is called JFrame.
A String
is a bunch of characters. It’s like having several char
values in a row. So, with the myTitle
variable declared to be of type String
, assigning “Blank Frame”
to the myTitle
variable makes sense in Listing 4-6. The String
class is declared in the Java API.
A Java JFrame is a lot like a window. (The only difference is that you call it a JFrame instead of a window.) To keep Listing 4-6 short and sweet, I decided not to put anything in my frame — no buttons, no fields, nothing.
Even with a completely empty frame, Listing 4-6 uses tricks that I don’t describe until later in this book. So don’t try reading and interpreting every word of Listing 4-6. The big thing to get from Listing 4-6 is that the program has two variable declarations. In writing the program, I made up two variable names — myTitle
and myFrame
. According to the declarations, myTitle
is of type String
, and myFrame
is of type JFrame
.
You can look up String
and JFrame
in Java’s API documentation. But, even before you do, I can tell you what you’ll find. You’ll find that String
and JFrame
are the names of Java classes. So, that’s the big news. Every class is the name of a reference type. You can reserve amountInAccount
for double
values by writing
double amountInAccount;
or by writing
double amountInAccount = 50.22;
You can also reserve myFrame
for a JFrame
value by writing
JFrame myFrame;
or by writing
JFrame myFrame = new JFrame();
Now, when you declare a variable to have type int
, you can visualize what that declaration means in a fairly straightforward way. It means that, somewhere inside the computer’s memory, a storage location is reserved for that variable’s value. In the storage location is a bunch of bits. The arrangement of the bits assures that a certain whole number is represented.
That explanation is fine for primitive types like int
or double
, but what does it mean when you declare a variable to have a reference type? What does it mean to declare variable myFrame
to be of type JFrame
?
Well, what does it mean to declare i thank You God to be an E. E. Cummings poem? What would it mean to write the following declaration?
EECummingsPoem ithankYouGod;
It means that a class of things is EECummingsPoem
, and ithankYouGod
refers to an instance of that class. In other words, ithankYouGod
is an object belonging to the EECummingsPoem
class.
Because JFrame
is a class, you can create objects from that class. (See Chapter 1.) Each object (each instance of the JFrame
class) is an actual frame — a window that appears on the screen when you run the code in Listing 4-6. By declaring the variable myFrame
to be of type JFrame
, you’re reserving the use of the name myFrame
. This reservation tells the computer that myFrame
can refer to an actual JFrame
-type object. In other words, myFrame
can become a nickname for one of the windows that appears on the computer screen. Figure 4-10 illustrates the situation.
An Import Declaration
It’s always good to announce your intentions up front. Consider the following classroom lecture:
“Today, in our History of Film course, we’ll be discussing the career of actor Lionel Herbert Blythe Barrymore.
“Born in Philadelphia, Barrymore appeared in more than 200 films, including It’s a Wonderful Life, Key Largo, and Dr. Kildare’s Wedding Day. In addition, Barrymore was a writer, composer, and director. Barrymore did the voice of Ebenezer Scrooge every year on radio. . . .”
Interesting stuff, heh? Now compare the paragraphs above with a lecture in which the instructor doesn’t begin by introducing the subject:
“Welcome once again to the History of Film.
“Born in Philadelphia, Lionel Barrymore appeared in more than 200 films, including It’s a Wonderful Life, Key Largo, and Dr. Kildare’s Wedding Day. In addition, Barrymore (not Ethel, John, or Drew) was a writer, composer, and director. Lionel Barrymore did the voice of Ebenezer Scrooge every year on radio. . . .”
Without a proper introduction, a speaker may have to remind you constantly that the discussion is about Lionel Barrymore and not about some other Barrymore. The same is true in a Java program. Look again at Listing 4-6:
import javax.swing.JFrame;
class ShowAFrame {
public static void main(String args[]) {
JFrame
myFrame = new JFrame
();
In Listing 4-6, you announce in the introduction (in the import declaration) that you’re using JFrame
in your Java class. You clarify what you mean by JFrame
with the full name javax.swing.JFrame
. (Hey! Didn’t the first lecturer clarify with the full name “Lionel Herbert Blythe Barrymore?”) After announcing your intentions in the import declaration, you can use the abbreviated name JFrame in your Java class code.
If you don’t use an import declaration, then you have to repeat the full javax.swing.JFrame
name wherever you use the name JFrame in your code. For example, without an import declaration, the code of Listing 4-6 would look like this:
class ShowAFrame {
public static void main(String args[]) {
javax.swing.JFrame
myFrame =
new
javax.swing.JFrame
();
String myTitle = “Blank Frame”;
myFrame.setTitle(myTitle);
myFrame.setSize(3200, 200);
myFrame.setDefaultCloseOperation
(
javax.swing.JFrame
.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
}
Creating New Values by Applying Operators
What could be more comforting than your old friend, the plus sign? It was the first thing that you learned about in elementary school math. Almost everybody knows how to add 2 and 2. In fact, in English usage, adding 2 and 2 is a metaphor for something that’s easy to do. Whenever you see a plus sign, a cell in your brain says, “Thank goodness — it could be something much more complicated.”
So Java has a plus sign. You can use it for several purposes. You can use the plus sign to add two numbers, like this:
int apples, oranges, fruit;
apples = 5;
oranges = 16;
fruit = apples + oranges;
You can also use the plus sign to paste String
values together:
String startOfChapter =
“It’s three in the morning. I’m dreaming about the “+
“history course that I failed in high school.”;
System.out.println(startOfChapter);
This can be handy because in Java, you’re not allowed to make a String
straddle from one line to another. In other words, the following code wouldn’t work at all:
String thisIsBadCode =
“It’s three in the morning. I’m dreaming about the
history course that I failed in high school.”;
System.out.println(thisIsBadCode);
You can even use the plus sign to paste numbers next to String
values.
int apples, oranges, fruit;
apples = 5;
oranges = 16;
fruit = apples + oranges;
System.out.println(“You have “ + fruit +
“ pieces of fruit.”);
Of course, the old minus sign is available, too (but not for String
values).
apples = fruit - oranges;
Use an asterisk (*
) for multiplication and a slash (/
) for division.
double rate, pay;
int hours;
rate = 6.25;
hours = 35;
pay = rate * hours;
System.out.println(pay);
For an example using division, refer to Listing 4-3.
Another useful arithmetic operator is called the remainder operator. The symbol for the remainder operator is the percent sign (%
). When you put System.out.println(11 % 4)
in your program, the computer prints 3
. It does this because 4 goes into 11 who-cares-how-many times with a remainder of 3. The remainder operator turns out to be fairly useful. Listing 4-7 has an example.
Listing 4-7: Making Change
import static java.lang.System.out;
class MakeChange {
public static void main(String args[]) {
int total = 248;
int quarters = total / 25;
int whatsLeft = total % 25;
int dimes = whatsLeft / 10;
whatsLeft = whatsLeft % 10;
int nickels = whatsLeft / 5;
whatsLeft = whatsLeft % 5;
int cents = whatsLeft;
out.println(“From “ + total + “ cents you get”);
out.println(quarters + “ quarters”);
out.println(dimes + “ dimes”);
out.println(nickels + “ nickels”);
out.println(cents + “ cents”);
}
}
Figure 4-11 shows a run of the code in Listing 4-7. You start with a total of 248 cents. Then
quarters = total / 25
divides 248 by 25, giving 9. That means you can make 9 quarters from 248 cents. Next,
whatsLeft = total % 25
divides 248 by 25 again, and puts only the remainder, 23, into whatsLeft
. Now you’re ready for the next step, which is to take as many dimes as you can out of 23 cents.
Initialize once, assign often
Listing 4-7 has three lines that put values into the variable whatsLeft
:
int
whatsLeft = total % 25;
whatsLeft = whatsLeft % 10;
whatsLeft = whatsLeft % 5;
Only one of these lines is a declaration. The other two lines are assignment statements. That’s good because you can’t declare the same variable more than once (not without creating something called a block). If you goof and write
int
whatsLeft = total % 25;
int
whatsLeft = whatsLeft % 10;
in Listing 4-7, you see an error message (whatsLeft is already defined
) when you try to compile your code.
The increment and decrement operators
Java has some neat little operators that make life easier (for the computer’s processor, for your brain, and for your fingers). Altogether, four such operators exist — two increment operators and two decrement operators. The increment operators add 1, and the decrement operators subtract 1. The increment operators use double plus signs (++
), and the decrement operators use double minus signs (--
). To see how they work, you need some examples. The first example is in Figure 4-12.
Figure 4-13 shows a run of the program in Figure 4-12. In this horribly uneventful run, the count of bunnies prints three times.
The double plus signs go by two names, depending on where you put them. When you put the ++
before a variable, the ++
is called the preincrement operator. (The pre stands for before.)
The word before has two meanings:
You put ++
before the variable.
The computer adds 1 to the variable’s value before the variable is used in any other part of the statement.
To understand this, look at the bold line in Figure 4-12. The computer adds 1 to numberOfBunnies
(raising the value of numberOfBunnies
to 29
) and then prints 29 onscreen.
An alternative to preincrement is postincrement. (The post stands for after.) The word after has two different meanings:
You put ++
after the variable.
The computer adds 1 to the variable’s value after the variable is used in any other part of the statement.
To see more clearly how postincrement works, look at the bold line in Figure 4-14. The computer prints the old value of numberOfBunnies
(which is 28
) on the screen, and then the computer adds 1 to numberOfBunnies
, which raises the value of numberOfBunnies
to 29
.
Figure 4-15 shows a run of the code in Figure 4-14. Compare Figure 4-15 with the run in Figure 4-13:
With preincrement in Figure 4-13, the second number is 29.
With postincrement in Figure 4-15, the second number is 28.
In Figure 4-15, 29 doesn’t show onscreen until the end of the run, when the computer executes one last out.println(numberOfBunnies)
.
In addition to preincrement and postincrement, Java has two operators that use --
. These operators are called predecrement and postdecrement.
With predecrement (--numberOfBunnies
), the computer subtracts 1 from the variable’s value before the variable is used in the rest of the statement.
With postdecrement (numberOfBunnies--
), the computer subtracts 1 from the variable’s value after the variable is used in the rest of the statement.
Assignment operators
If you read the preceding section, which is about operators that add 1, you may be wondering whether you can manipulate these operators to add 2 or add 5 or add 1000000. Can you write numberOfBunnies++++
and still call yourself a Java programmer? Well, you can’t. If you try it, an error message appears when you try to compile your code.
So what can you do? As luck would have it, Java has plenty of assignment operators that you can use. With an assignment operator, you can add, subtract, multiply, or divide by anything you want. You can do other cool operations, too. Listing 4-8 has a smorgasbord of assignment operators (the things with equal signs). Figure 4-16 shows the output from running Listing 4-8.
Listing 4-8: Assignment Operators
class UseAssignmentOperators {
public static void main(String args[]) {
int numberOfBunnies = 27;
int numberExtra = 53;
numberOfBunnies += 1;
System.out.println(numberOfBunnies);
numberOfBunnies += 5;
System.out.println(numberOfBunnies);
numberOfBunnies += numberExtra;
System.out.println(numberOfBunnies);
numberOfBunnies *= 2;
System.out.println(numberOfBunnies);
System.out.println(numberOfBunnies -= 7);
System.out.println(numberOfBunnies = 100);
}
}
Listing 4-8 shows how versatile Java’s assignment operators are. With the assignment operators, you can add, subtract, multiply, or divide a variable by any number. Notice how += 5
adds 5 to numberOfBunnies
, and how *= 2
multiplies numberOfBunnies
by 2. You can even use another expression’s value (in Listing 4-8, numberExtra
) as the number to be applied.
The last two lines in Listing 4-8 demonstrate a special feature of Java’s assignment operators. You can use an assignment operator as part of a larger Java statement. In the next to last line of Listing 4-8, the operator subtracts 7 from numberOfBunnies
, decreasing the value of numberOfBunnies
from 172
to 165
. Then the whole assignment business is stuffed into a call to System.out.println
, so 165 prints onscreen.
Lo and behold, the last line of Listing 4-8 shows how you can do the same thing with Java’s plain-old equal sign. The thing that I call an assignment statement near the start of this chapter is really one of the assignment operators that I describe in this section. Therefore, whenever you assign a value to something, you can make that assignment be part of a larger statement.
For a richer explanation of this kind of thing, see the sidebar, “Statements and expressions,” earlier in this chapter.