In this code when I pass instance member of class hello which is (int a) in this() statement in default constructor, error is shown:"cannot refrence a before supertype constructor has been called." but when I make the (int a) as static , code works properly.What is the reason?
class hello{
int a=10;
hello (){
this(a);
System.out.println("default constructor ");
System.out.println(this);
}
hello (int b){
System.out.println("1 parameter constructor");
}
}
class Test2{
public static void main (String arg[])
{
hello h1=new hello();
System.out.println(h1);
}
}
CodePudding user response:
From section 8.8.7.1 of the JLS:
An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.
That's exactly what you're trying to do. The reason for this rule is that at the time the explicit constructor invocation statement is executed, any field initializers (and other instance initializers) will not have been executed, so it would basically be pointless. (And if you try to invoke an instance method, that would be acting on an uninitialized object.) While it would be feasible for Java not to have this rule, it prevents a lot of confusing behavior.
CodePudding user response:
The this(a)
is doing constructor chaining. And the order of constructor evaluation is going to be:
Object()
hello(int)
hello()
And the hello(int)
constructor is going to (implicitly) perform the initialization of hello
's instance fields; i.e. a = 10;
.
But when hello()
calls (i.e. chains) this(a)
, the hello(int)
constructor hasn't run yet! So a
has not been initialized, and its value may not be used. (Actually, in practice, a
may have been default initialized, but that isn't enough.) The precise rules governing this are in the JLS; see Jon Skeet's answer.
In fact this rule is a good thing. If you were permitted to use a
at that point, it would have the unexpected value 0
.
To be honest, what you are actually doing here doesn't make sense. The parameter you pass to the hello(int)
constructor isn't used.