Scope and Lifetime of Variables
A hotel room key works only for your room, and only until you check out. Your name on the guest register lasts longer: the whole stay. Variables are similar. Scope is where in the code a variable's name works. Lifetime is how long the variable actually exists while the program runs. Most of the time the rule is simple: a variable belongs to the curly braces it was declared in.
The Rule of the Braces
A block is any code between { and }. A local variable can be used from the line where it's declared to the end of its block, including any blocks inside it. After the closing brace, its name no longer exists.
public class Journey {
public static void main(String[] args) {
String city = "Mysuru";
if (city.length() > 3) {
int fare = 350;
System.out.println(city + " fare: Rs. " + fare);
}
// fare no longer exists here
for (int i = 1; i <= 2; i++) {
System.out.println("Stop " + i + " on the way to " + city);
}
// i no longer exists here
}
}Mysuru fare: Rs. 350
Stop 1 on the way to Mysuru
Stop 2 on the way to MysuruHow it works
- Line 3:
cityis declared directly inmain, so it can be used anywhere inmainafter this line, including inside theifand the loop. - Line 5:
fareis declared inside theifblock. It exists only until the}on line 7. - Line 10:
iis declared in theforloop header. It exists only inside the loop.
Using fare after line 7 gives the same error you'd get for a misspelled name, because outside its block the name simply doesn't exist:
Journey.java:7: error: cannot find symbol
System.out.println(fare);
^
symbol: variable fare
location: class JourneyTry it yourself: move the line int fare = 350; above the if. Can you now print fare after the if block?
Scope of Each Kind of Variable
| Kind | Scope: where the name works | Lifetime: how long it exists |
|---|---|---|
| Block variable | From its declaration to the end of its block | Until the block finishes |
Loop variable (for (int i ...)) | Inside the loop only | Until the loop ends |
| Method parameter | The whole method body | One method call |
| Instance variable | The whole class (every non-static method) | As long as its object exists |
| Static variable | The whole class, and other classes through ClassName.name | As long as the class is loaded |
Shadowing: Same Name, Inner Scope
A local variable or parameter may have the same name as a field. Inside that method, the local one hides (shadows) the field:
public class Shadow {
static String city = "Delhi";
public static void main(String[] args) {
String city = "Kochi";
System.out.println("Local city: " + city);
System.out.println("Field city: " + Shadow.city);
}
}Local city: Kochi
Field city: DelhiLine 6 uses the nearest city, the local one. Line 7 reaches the field by writing the class name in front. With instance variables, you'll write this.city instead, as Level 2 shows.
Two local variables with the same name in overlapping scopes are not allowed: declaring int fare inside the if when main already has a fare gives variable fare is already defined.
Common Mistakes
Declaring inside a block and using it after. If you need a value after an if or loop, declare the variable before the block and assign it inside.
Expecting a loop variable to keep its last value. for (int i = 0; ...) makes i disappear when the loop ends. Declare int i; before the loop if you need it later.
Confusing a shadowing local with the field. Changing the local doesn't change the field, which can look like a bug that "ignores" your assignment.
Practice
- Easy: In
Journey, try to printiafter the loop. Read the error, then fix it by declaringibefore the loop. - Harder: Write a program that works out a total fare inside an
if(only when the passenger count is above 0) and prints the total after theif. Where must the variable be declared?
Key Takeaways
Was this tutorial helpful?