Local variables & scope in Java
Locals live on the stack frame and die when the method returns.
A method's private notes
Variables declared inside a method, including its parameters, are local. They exist only while that call runs and vanish when it returns. No other method can see them.
static int square(int n) { // n is local
int result = n * n; // so is result
return result;
} // n and result are gone nowYour turn
visit() is called three times. What prints?
static int visit() {
int seen = 0;
seen += 5;
return seen;
}
void main() {
visit();
visit();
System.out.println(visit());
}1550
Show the answer
5. Each call creates a new seen starting at 0, adds 5 and returns it. Nothing carries over between calls.
Where locals live
Locals live in the call's stack frame. Every call, even of the same method, gets brand-new copies; returning destroys the frame and its locals. (Objects a local *refers to* live on the heap.) To remember something between calls, use a field.
static int count = 0; // field: survives
static int next() {
count++;
return count; // 1, 2, 3, ...
}No default values
Locals get no default value. Reading one before it's definitely assigned is a compile error: variable x might not have been initialized. The compiler doesn't evaluate y > 0, so it sees a path where x was never set.
int x;
int y = 3;
if (y > 0) {
x = 1;
}
System.out.println(x); // errorYour turn
vip is true, so total gets 100... right?
int total;
boolean vip = true;
if (vip) {
total = 100;
}
System.out.println(total);1000Compile error
Show the answer
Compile error. vip is an ordinary variable, so the compiler doesn't assume the if runs. It sees a path where total is unassigned. Fix: int total = 0;.
Sharing a value between methods
static void setUp() {
int limit = 10;
}
static void run() {
System.out.println(limit);
}limit is local to setUp; run can't see it: cannot find symbol.
static void run(int limit) {
System.out.println(limit);
}
// caller: run(10);Pass it as a parameter (or, if it must persist, make it a field).
In real projects
Because each call has its own frame, and each thread its own stack, local variables are naturally thread-safe. That's why web servers can run the same method for thousands of requests at once: methods that keep their state in locals don't step on each other.
Key takeaways
- Locals and parameters disappear when the method returns
- Each call (even of the same method) gets its own fresh copies
- Locals have no default value; reading an unassigned one won't compile
- Another method can't see your locals
Inside the JVM, each frame stores locals in numbered slots, and a long or double takes up two slots while an int takes one.
Practice questions
What does this print?
static int next() {
int count = 0;
count++;
return count;
}
void main() {
next();
next();
System.out.println(next());
}- 3
- 1
- 0
- 2
Check your answer
1. Each call creates a new count starting at 0, so every call returns 1.
What does this print?
int x;
int y = 3;
if (y > 0) {
x = 1;
}
System.out.println(x);- 1
- 0
- Compile error
Check your answer
Compile error. The compiler doesn't evaluate y > 0, so it sees a path where x is never assigned: variable x might not have been initialized. Locals have no default value.