NUMBER_FLAGS
.
The exam will not always follow these conventions to make questions about identifiers trickier. By contrast, questions on other topics generally do follow standard conventions. We recommend you follow these conventions on the job.
Declaring Multiple Variables
You can also declare and initialize multiple variables in the same statement. How many variables do you think are declared and initialized in the following example?
void sandFence() { String s1, s2; String s3 = "yes", s4 = "no"; }
Four String
variables were declared: s1
, s2
, s3
, and s4
. You can declare many variables in the same declaration as long as they are all of the same type. You can also initialize any or all of those values inline. In the previous example, we have two initialized variables: s3
and s4
. The other two variables remain declared but not yet initialized.
This is where it gets tricky. Pay attention to tricky things! The exam will attempt to trick you. Again, how many variables do you think are declared and initialized in the following code?
void paintFence() { int i1, i2, i3 = 0; }
As you should expect, three variables were declared: i1
, i2
, and i3
. However, only one of those values was initialized: i3
. The other two remain declared but not yet initialized. That's the trick. Each snippet separated by a comma is a little declaration of its own. The initialization of i3
only applies to i3
. It doesn't have anything to do with i1
or i2
despite being in the same statement. As you will see in the next section, you can't actually use i1
or i2
until they have been initialized.
Another way the exam could try to trick you is to show you code like this line:
int num, String value; // DOES NOT COMPILE
This code doesn't compile because it tries to declare multiple variables of different types in the same statement. The shortcut to declare multiple variables in the same statement is legal only when they share a type.
To make sure you understand this, see if you can figure out which of the following are legal declarations:
4: boolean b1, b2; 5: String s1 = "1", s2; 6: double d1, double d2; 7: int i1; int i2; 8: int i3; i4;
Lines 4 and 5 are legal. They each declare two variables. Line 4 doesn't initialize either variable, and line 5 initializes only one. Line 7 is also legal. Although int
does appear twice, each one is in a separate statement. A semicolon (;
) separates statements in Java. It just so happens there are two completely different statements on the same line.
Line 6 is not legal. Java does not allow you to declare two different types in the same statement. Wait a minute! Variables d1
and d2
are the same type. They are both of type double
. Although that's true, it still isn't allowed. If you want to declare multiple variables in the same statement, they must share the same type declaration and not repeat it.
Line 8 is not legal. Again, we have two completely different statements on the same line. The second one on line 8 is not a valid declaration because it omits the type. When you see an oddly placed semicolon on the exam, pretend the code is on separate lines and think about whether the code compiles that way. In this case, the last two lines of code could be rewritten as follows:
int i1; int i2; int i3; i4;
Looking at the last line on its own, you can easily see that the declaration is invalid. And yes, the exam really does cram multiple statements onto the same line—partly to try to trick you and partly to fit more code on the screen. In the real world, please limit yourself to one declaration per statement and line. Your teammates will thank you for the readable code.
Initializing Variables
Before you can use a variable, it needs a value. Some types of variables get this value set automatically, and others require the programmer to specify it. In the following sections, we look at the differences between the defaults for local, instance, and class variables.
Creating Local Variables
A local variable is a variable defined within a constructor, method, or initializer block. For simplicity, we focus primarily on local variables within methods in this section, although the rules for the others are the same.
Final Local Variables
The final
keyword can be applied to local variables and is equivalent to declaring constants in other languages. Consider this example:
5: final int y = 10; 6: int x = 20; 7: y = x + 10; // DOES NOT COMPILE
Both variables are set, but y
uses the final
keyword. For this reason, line 7 triggers a compiler error since the value cannot be modified.
The final
modifier can also be applied to local variable references. The following example uses an int[]
array object, which you learn about in Chapter 4.
5: final int[] favoriteNumbers = new int[10]; 6: favoriteNumbers[0] = 10; 7: favoriteNumbers[1] = 20; 8: favoriteNumbers = null; // DOES NOT COMPILE
Notice that we can modify the content, or data, in the array. The compiler error isn't until line 8, when we try to change the value of the reference favoriteNumbers
.
Uninitialized Local Variables
Local variables do not have a default value and must be initialized before use. Furthermore, the compiler will report an error if you try to read an uninitialized value. For example, the following code generates a compiler error:
4: public int notValid() { 5: int y = 10; 6: int x; 7: int reply = x + y; // DOES NOT COMPILE 8: return reply; 9: }
The y
variable is initialized to 10
. By contrast, x
is not initialized before it is used in the expression on line 7, and the compiler generates an error. The compiler is smart enough to recognize variables that have been initialized after their declaration but before they are used. Here's an example:
public int valid() { int y = 10; int x; // x is declared here x = 3; // x is initialized here int z; // z is declared here but never initialized or used int reply = x + y; return reply; }
In this example, x
is declared, initialized, and used in separate lines. Also, z
is declared but never used, so it is not required to be initialized.
The compiler is also smart enough to recognize initializations that are more complex. In this example, there are two branches of code:
public void findAnswer(boolean check) { int answer; int otherAnswer; int onlyOneBranch; if (check) { onlyOneBranch = 1; answer = 1; } else { answer = 2; } System.out.println(answer); System.out.println(onlyOneBranch); // DOES NOT COMPILE }
The answer
variable is initialized in both branches of the if
statement, so the compiler is perfectly happy. It knows that regardless of whether check
is true
or false
,