Consider the following Java class declaration:
public class Test {
private final int defaultValue = 10;
private int var;
public Test() {
this(defaultValue); // <-- Compiler error: cannot reference defaultValue before supertype constructor has been called.
}
public Test(int i) {
var = i;
}
}
The code will not compile, with the compiler complaining about the line I've highlighted above. Why is this error happening and what's the best workaround?
The reason why the code would not initially compile is because
defaultValue
is an instance variable of the classTest
, meaning that when an object of typeTest
is created, a unique instance ofdefaultValue
is also created and attached to that particular object. Because of this, it is not possible to referencedefaultValue
in the constructor, as neither it, nor the object have been created yet.The solution is to make the final variable
static
:By making the variable
static
, it becomes associated with the class itself, rather than instances of that class and is shared amongst all instances ofTest
. Static variables are created when the JVM first loads the class. Since the class is already loaded when you use it to create an instance, the static variable is ready to use and so can be used in the class, including the constructor.References:
Rule : Every constructor must execute super class's constructor before executing itself.
So the first line of every constructor is super() or may be this() and you are send the defaultValue to the this class constructor which(defaultValue) is not existed yet hence there is compile time error.
You can made defaultValue as static and since static variable is created as class is loaded to memory so defaultValue is available at the line this(defaultValue).
Until your object is not been constructed default values to the variables won't be set hence if you want their default values to be set at the time of construction make them
static
or explicitly set them before.It is because the
defaultValue
is an member ofTest
's instance which is under construction (not yet created)If you had it
static
it were loaded when your class loads by classloadersconstructor is called at the time of object creation so no reference to varable is recognized by compiler as compiler has no knowledge regarding instance variable as object is not created yet.
Actually this is not correct answer, as during the creation of object, fields initialization instructions execute before the constructor. You can debug the object creation process and see that on your own. I myself am confused about this problem as well.. for example, if you will change a bit and first constructor will be:
This will work.. so, when the first/null constructor calls another, it is not working for a strange reason, even if I explicitly call super(); before.
The most relevant explanation would be, that JVM loads declarations in the memory, but NO CONSTRUCTOR IS ABLE TO REACH ANY INSTANCE VARIABLE/FIELD before it gets executed entirely.