Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
A.java:[7,17] cannot reference this before supertype constructor has been called
Compilation is successful if either of these changes are made:
B
is private instead of public
line 7 reads
new B(A);
instead of
new 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.
javac
and the
Java Puzzlers
behavior is used for reference in this discussion.
I was able to cut down the snippet to the following:
public class A {
class B extends A {
void foo() {
new B() { }; // DOES NOT COMPILE!!
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:
public class Outer { // "A"
class Inner1 extends Outer {} // "B"
class Inner2 extends Inner1 {} // "B" anonymous
// DOES NOT COMPILE!!
The problem is that due to how default constructor is defined, we really have the following:
// Same as above but with default constructor included explicitly
public class Outer {
class Inner1 extends Outer {
Inner1() { super(); }
class Inner2 extends Inner1 {
Inner2() { super(); }
// STILL DOES NOT COMPILE!!
The problem is that Inner2
's superclass is itself an inner class Inner1
, thus making Inner2
'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-this
expression:
// "brute-force" fix
public class Outer {
class Inner1 extends Outer {
Inner1() { super(); }
class Inner2 extends Inner1 {
Inner2() { Outer.this.super(); }
// NOW COMPILES!
However, the puzzle prescribes that such complicated situation is best avoided in the first place. Here are some quotes:
This compiles, but it is mind-numbingly complex. There is a better solution: Whenever you write a member class, ask yourself, Does this class really need an enclosing instance? If the answer is no, make it static
. Inner classes are sometimes useful, but they can easily introduce complications that make a program difficult to understand. They have complex interactions with generics (Puzzle 89), reflection (Puzzle 80), and inheritance (this puzzle). If you declare Inner1
to be static
, the problem goes away. If you also declare Inner2
to be static
, you can actually understand what the program does: a nice bonus indeed.
In summary, it is rarely appropriate for one class to be both an inner class and a subclass of another. More generally, it is rarely appropriate to extend an inner class; if you must, think long and hard about the enclosing instance. Also, prefer static
nested classes to non-static
. Most member classes can and should be declared static
.
–
–
Not sure what the goal is exactly, but try this. Note I also cut out the passing of A as an argument as being non-static classes they are already linked. I included the syntax for referring to the outer class "this" for those situations were the inner class may cover up an outer class field/method
public class A {
protected String field = "a";
public class B extends A {
protected String field = "b";
public B() {
System.out.println("" + A.this.field + " " + this.field);
@Override
void foo() {
System.out.println("b.foo()");
void foo() {
A a = new A();
a.field = "a2";
B b = a.new B() {
@Override
void foo() {
System.out.println("b.anon.foo()");
b.foo();
public static void main(String[] args) {
new A().foo();
Running this will output:
b.anon.foo()
Hope this helps!
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.