Java doesn’t allow you to use an variable that may not have been initialized within a method scope. An uninitialized variable within a class scope may still be returned by a class method, and the value defaults to null.
Why the different treatment of the two different scopes?
public class TestClass {
Integer i;
Double d;
public TestClass() {
d = 1d;
}
public Double getD() {
return d;
}
public Integer getI() {
return i;
}
// public Integer getSomeInt() {
// Integer i;
// return i;
// }
public static void main(String[] args) {
TestClass myClass = new TestClass();
System.out.println(myClass.getI().getClass());
}
}
This results in a NullPointerException, but returning i within getSomeInt() is a compiler error because “the variable may not have been initialized”.
The reason behind this are the limits of Java’s static code analysis. The compiler is able to prove beyond doubt that you will not read a stack-allocated local var before initializing it. This is impossible to do for heap-allocated memory and therefore Java mandates that all heap-allocated storage be zeroed out before exposing a pointer to it.
The consequence of this rule is that everything heap-allocated has a default value of zero (false, null, whatever the binary zero amounts to for the type).