Will Java Final variables have default values?

http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html, chapter “Initializing Instance Members”:

The Java compiler copies initializer blocks into every constructor.

That is to say:

{
    printX();
}

Test() {
    System.out.println("const called");
}

behaves exactly like:

Test() {
    printX();
    System.out.println("const called");
}

As you can thus see, once an instance has been created, the final field has not been definitely assigned, while (from http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.2):

A blank final instance variable must be definitely assigned at
the end of every constructor of the class in which it is
declared; otherwise a compile-time error occurs.

While it does not seem to be stated explitely in the docs (at least I have not been able to find it), a final field must temporary take its default value before the end of the constructor, so that it has a predictable value if you read it before its assignment.

Default values: http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5

On your second snippet, x is initialized on instance creation, so the compiler does not complain:

Test() {
    printX();
    x = 7;
    printX();
    System.out.println("const called");
}

Also note that the following approach doesn’t work. Using default value of final variable is only allowed through a method.

Test() {
    System.out.println("Here x is " + x); // Compile time error : variable 'x' might not be initialized
    x = 7;
    System.out.println("Here x is " + x);
    System.out.println("const called");
}

Leave a Comment