.
Читать онлайн книгу.{ 5: int a, var b = 3; // DOES NOT COMPILE 6: var n = null; // DOES NOT COMPILE 7: }
Line 5 wouldn't work even if you replaced var
with a real type. All the types declared on a single line must be the same type and share the same declaration. We couldn't write int a, int v = 3;
either.
Line 6 is a single line. The compiler is being asked to infer the type of null
. This could be any reference type. The only choice the compiler could make is Object
. However, that is almost certainly not what the author of the code intended. The designers of Java decided it would be better not to allow var
for null
than to have to guess at intent.
var
cannot be initialized with a null
value without a type, it can be reassigned a null
value after it is declared, provided that the underlying data type is a reference type.
Let's try another example. Do you see why this does not compile?
public int addition(var a, var b) { // DOES NOT COMPILE return a + b; }
In this example, a
and b
are method parameters. These are not local variables. Be on the lookout for var
used with constructors, method parameters, or instance variables. Using var
in one of these places is a good exam trick to see if you are paying attention. Remember that var
is only used for local variable type inference!
There's one last rule you should be aware of: var
is not a reserved word and allowed to be used as an identifier. It is considered a reserved type name. A reserved type name means it cannot be used to define a type, such as a class, interface, or enum
. Do you think this is legal?
package var; public class Var { public void var() { var var = "var"; } public void Var() { Var var = new Var(); } }
Believe it or not, this code does compile. Java is case sensitive, so Var
doesn't introduce any conflicts as a class name. Naming a local variable var
is legal. Please don't write code that looks like this at your job! But understanding why it works will help get you ready for any tricky exam questions the exam creators could throw at you.
var in the Real World
The var
keyword is great for exam authors because it makes it easier to write tricky code. When you work on a real project, you want the code to be easy to read.
Once you start having code that looks like the following, it is time to consider using var
:
PileOfPapersToFileInFilingCabinet pileOfPapersToFile = new PileOfPapersToFileInFilingCabinet();
You can see how shortening this would be an improvement without losing any information:
var pileOfPapersToFile = new PileOfPapersToFileInFilingCabinet();
If you are ever unsure whether it is appropriate to use var
, we recommend “Local Variable Type Inference: Style Guidelines,” which is available at the following location.
https://openjdk.java.net/projects/amber/LVTIstyle.html
Managing Variable Scope
You've learned that local variables are declared within a code block. How many variables do you see that are scoped to this method?
public void eat(int piecesOfCheese) { int bitesOfCheese = 1; }
There are two variables with local scope. The bitesOfCheese
variable is declared inside the method. The piecesOfCheese
variable is a method parameter. Neither variable can be used outside of where it is defined.
Limiting Scope
Local variables can never have a scope larger than the method they are defined in. However, they can have a smaller scope. Consider this example:
3: public void eatIfHungry(boolean hungry) { 4: if (hungry) { 5: int bitesOfCheese = 1; 6: } // bitesOfCheese goes out of scope here 7: System.out.println(bitesOfCheese); // DOES NOT COMPILE 8: }
The variable hungry
has a scope of the entire method, while the variable bitesOfCheese
has a smaller scope. It is only available for use in the if
statement because it is declared inside of it. When you see a set of braces ({}
) in the code, it means you have entered a new block of code. Each block of code has its own scope. When there are multiple blocks, you match them from the inside out. In our case, the if
statement block begins at line 4 and ends at line 6. The method's block begins at line 3 and ends at line 8.
Since bitesOfCheese
is declared in an if
statement block, the scope is limited to that block. When the compiler gets to line 7, it complains that it doesn't know anything about this bitesOfCheese
thing and gives an error.
Remember that blocks can contain other blocks. These smaller contained blocks can reference variables defined in the larger scoped blocks, but not vice versa. Here's an example:
16: public void eatIfHungry(boolean hungry) { 17: if (hungry) { 18: int bitesOfCheese = 1; 19: { 20: var teenyBit = true; 21: System.out.println(bitesOfCheese); 22: } 23: } 24: System.out.println(teenyBit); // DOES NOT COMPILE 25: }
The variable defined on line 18 is in scope until the block ends on line 23. Using it in the smaller block from lines 19 to 22 is fine. The variable defined on line 20 goes out of scope on line 22. Using it on line 24 is not allowed.
Tracing Scope
The exam will attempt to trick you with various questions on scope. You'll probably see a question that appears to be about something complex and fails to compile because one of the variables is out of scope.
Let's try one. Don't worry if you aren't familiar with if
statements or while
loops yet. It doesn't matter what the code does since we are talking about scope. See if you can figure out on which line each of the five local variables goes into and out of scope:
11: public void eatMore(boolean hungry, int amountOfFood) { 12: int roomInBelly = 5; 13: if (hungry) { 14: var timeToEat = true; 15: while (amountOfFood> 0) { 16: int amountEaten = 2; 17: roomInBelly = roomInBelly - amountEaten; 18: amountOfFood = amountOfFood - amountEaten; 19: } 20: } 21: System.out.println(amountOfFood); 22: }
This method does compile. The first step in figuring out the scope is to identify the blocks of code. In this case, there are three blocks. You can tell this because there are three sets of braces. Starting from the innermost set, we can see where the while
loop's block starts and ends. Repeat this process as we go on for the if
statement block and method block. Table 1.10 shows the line numbers that each block starts and ends on.
TABLE 1.10 Tracking scope by block
Line | First line in block | Last line in block |
---|---|---|
while
|