This question already has an answer here:
Why do variables declared in a class have default values, but the variables declared inside methods, said to be "local variables", don't have default values in Java?
For example
class abc
{
int a;
public static void main(String ss[])
{
int b;
abc aa=new abc();
System.out.println(aa.a);
System.out.println(b);
}
}
In this above example variable a
has default value of 0 but variable b
gives error that it might not have been initialized.
Local variables Initialization
Variables declared in methods and in blocks are called local variables. Local variable are not initialized when they are created at method invocation. Therefore, a local variable must be initialized explicitly before being used. Otherwise the compiler will flag it as error when the containing method or block is executed.
Example:
The compiler complains that the local variable total used in println statement at (1) may not be initialized. Initializing the local variable total before usage solves the problem:
Fields initialization
If no initialization is provided for an instance or static variable, either when declared or in an initializer block, then it is implicitly initialized with the default value of its type. An instance variable is initialized with the default value of its type each time the class is instantiated, that is for every object created from the class. A static variable is initialized with the default value of its type when the class is first loaded.
tl;dr: It was more or less an arbitrary choice
If you ask me, it was a mistake that Java has default values for instance variables. The compiler should have forced the programmer to initialize it before like it is the case for local variables.
The rationale behind the default values is safety. When an object is instantiated, a chunk of memory will be allocated for the object which contains where the instance variables are pointing to etc. The Java designers decided it would be a good idea to wipe this part of memory with zeros and nulls. This way you will never read garbage that happened to be there before the object was allocated. They could have forced initialization; there is nothing fundamental about the choice. It probably made things easy to implement and made enough sense to the designers of Java.
In case of local variables, the designers chose to force initialization (or perhaps it's more accurate to say they chose to not do any kind of initialization when a local variable is only declared, and thus the most logical behavior of the compiler was to force initialization of the variable before use).
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
and the bytecode from
javap -c Abc
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 functionAbc()
!As field variable
e
is not assigned any value it will be 0 if primitive or null if a Object referenceAnd if you look at
doSomething()
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
I leave further bytecode comparison upto you ;) but I hope it is clear
All member variable have to load into heap so they have to initialized with default values when an instance of class is created. In case of local variables, they don't get loaded into heap they are stored in stack until they are being used before java 7, so we need to explicitly initialize them. Now the "Java Hotspot Server Compiler" performs "escape analysis" and decides to allocate some variables on the stack instead of the heap.