Uninitialized variables and members in Java

26,092

Solution 1

The rules for definite assignment are quite difficult (read chapter 16 of JLS 3rd Ed). It's not practical to enforce definite assignment on fields. As it stands, it's even possible to observe final fields before they are initialised.

Solution 2

The language defines it this way.

Instance variables of object type default to being initialized to null. Local variables of object type are not initialized by default and it's a compile time error to access an undefined variable.

See section 4.12.5 for SE7 (same section still as of SE14) http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5

Solution 3

Here's the deal. When you call

TestClass tc = new TestClass();

the new command performs four important tasks:

  1. Allocates memory on the heap for the new object.
  2. Initiates the class fields to their default values (numerics to 0, boolean to false, objects to null).
  3. Calls the constructor (which may re-initiate the fields, or may not).
  4. Returns a reference to the new object.

So your fields 'a' and 'b' are both initiated to null, and 'a' is re-initiated in the constructor. This process is not relevant for method calling, so local variable 'c' is never initialized.

HTH

PS: for the gravely insomniac, read this.

Solution 4

The compiler can figure out that c will never be set. The b variable could be set by someone else after the constructor is called, but before doSomething(). Make b private and the compiler may be able to help.

Solution 5

The compiler can tell from the code for doSomething() that c is declared there and never initialized. Because it is local, there is no possibility that it is initialized elsewhere.

It can't tell when or where you are going to call doSomething(). b is a public member. It is entirely possible that you would initialize it in other code before calling the method.

Share:
26,092
Yuval Adam
Author by

Yuval Adam

λf.(λx.f(x x)) (λx.f(x x))

Updated on September 02, 2020

Comments

  • Yuval Adam
    Yuval Adam over 2 years

    Consider this:

    public class TestClass {
        private String a;
        private String b;
        public TestClass()
        {
        a = "initialized";
        }
        public void doSomething()
        {
        String c;
            a.notify(); // This is fine
        b.notify(); // This is fine - but will end in an exception
        c.notify(); // "Local variable c may not have been initialised"
        }
    }
    

    I don't get it. "b" is never initialized but will give the same run-time error as "c", which is a compile-time error. Why the difference between local variables and members?

    Edit: making the members private was my initial intention, and the question still stands...