This question already has an answer here:
I wrote this piece of code and it seems compiler allows accessing uninitialized blank final field when accessed using 'this' keyword:
public class TestClass
{
public final int value1;
public int value2;
TestClass(int value) {
value2 = 2 + this.value1; // access final field using 'this' before initialization gives no compiler error
//value2 = 2 + value1; // uncomment it gives compile time error - variable value1 might not have been initialized
value1 = value;
}
public static void main(String args[]) {
TestClass tc = new TestClass(10);
System.out.println("\nTestClass Values : value1 = " + tc.value1 + " , value2 = " + tc.value2);
}
}
I tried compiling it on 1.5, 1.6, & 1.7 and got same result in all three of them.
To me it looks like compiler bug because compiler must throw error in this case but with 'this' keyword it doesn't and thus creates scope of coding error as it will go unnoticed by the programmer since no compile-time or run-time error will be thrown.
FEW POINTS WHY IT IS NOT A DUPLICATE
- all answers are explaining how it works and what JLS says, fine, but my real intent here is should that be allowed at the first place?
- my question here is more from programmer's point of view and not language semantics
In Java ints have a default value of 0, so even if you did not initialize it, the compiler has still assigned 0 as value.
Source: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Note that this does not apply to local variables, only field variables have a default value.
I used the following code
and the bytecode it generates is
If you notice JVM does a
getstatic
call in case of final andgetfield
in case of normal instance variable. Also now if you look at the specs for getstatic it saysSo if you use this with a final variable then it is initialize it. Not it will initialize
this.value1
and notvalue1
which is final. You still have to initialize it before using.This is not a bug. This a feature for Java Specification 1.6 and lower.
The final field can be accessed at any part of the code. There is no restriction about it.
The only restriction in case of final is that it has to be initialized before class instance is created.
When you use
this
, you express that it is element of the object that is being constructed.Since the specification 1.7 because of change we may say that this is bug in some implementation of compilers.
But since 1.8 the code will produce same error for
this.value1
orvalue1
.