Why doesn’t this code compile?
public class A {
public class B extends A {
public B(A a) { }
}
void foo() {
A a = new A();
new B(a) { };
}
}
A.java:[7,17] cannot reference this before supertype constructor has been called
Compilation is successful if either of these changes are made:
Bis private instead of public- line 7 reads
new B(A);instead ofnew B(A) { }
Using javac version: 1.6.0_20
It should be noted that Eclipse,
javac, and Intellij IDEA exhibit differences in behaviors with regards to these snippets.javacand the Java Puzzlers behavior is used for reference in this discussion.I was able to cut down the snippet to the following:
This scenario is discussed in Java Puzzlers, Puzzle 90: It’s Absurd, It’s a Pain, It’s Superclass!
The snippet given is the following:
The problem is that due to how default constructor is defined, we really have the following:
The problem is that
Inner2‘s superclass is itself an inner classInner1, thus makingInner2‘s default constructor illegal since it requires an enclosing instance to be supplied to the constructor.The "brute-force" way to fix the problem is to provide this explicitly with a qualified-
thisexpression:However, the puzzle prescribes that such complicated situation is best avoided in the first place. Here are some quotes: