As local variables are allocated on stack, memory chunk for a local variable is allocated when it is assigned with a value.
Take simple example
class Abc {
int i = -111;
int e;
int doSomething() {
int a = 10;
int b = a + i;
int c = b + 100;
Abc d = new Abc();
e = b + c + d.a;
return e + 1000;
}
}
and the bytecode from javap -c Abc
Compiled from "Abc.java"
class Abc {
int i;
int e;
Abc();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush -111
7: putfield #2 // Field i:I
10: return
int doSomething();
Code:
0: bipush 10
2: istore_1
3: iload_1
4: aload_0
5: getfield #2 // Field i:I
8: iadd
9: istore_2
10: iload_2
11: bipush 100
13: iadd
14: istore_3
15: new #3 // class Abc
18: dup
19: invokespecial #4 // Method "<init>":()V
22: astore 4
24: aload_0
25: iload_2
26: iload_3
27: iadd
28: aload 4
30: getfield #2 // Field i:I
33: iadd
34: putfield #5 // Field e:I
37: aload_0
38: getfield #5 // Field e:I
41: sipush 1000
44: iadd
45: ireturn
}
When a method is inovked a memory space in the stack called current frame is allocated
If you look carefully even int a=-111;
assignment happens in an implicit init function Abc()
!
int a = -111;
5: bipush -111
7: putfield #2 // Field a:I
As field variable e
is not assigned any value it will be 0 if primitive or null if a Object reference
And if you look at doSomething()
int a = 10;
0: bipush 10
for a local to be used the initial value needs to be pushed into stack in this case 10 . without this 'push' [initialization] a's value is not accessible to subsequent statements (as the value is not on the stack). once the value is pushed to stack other operations like iadd istore etc are carried out on the stack
below statement actually creates an object on the heap space and invokes init method. This is where un initialized variables like 'e' gets default values
15: new #3 // class Abc
18: dup
I leave further bytecode comparison upto you ;) but I hope it is clear