Nested Classes problem

E

Eric

I have the following nested class structure:

public class A {
public A() {}

public class B extends A{
public B(){}
}

public class C extends B{
public C(){} // <- error happens here
}
}

I get the following error:
"A.java": cannot reference this before supertype constructor has been called
at line 9, column 19

Is valid Java code/class structuring?

Thanks in advance for any help!
 
K

klynn47

I took your code and added the following and didn't get an error.

public static void main(String[] args) {
A a = new A();

C c = a.new C();
}
 
R

Ryan Stewart

Eric said:
I have the following nested class structure:

public class A {
public A() {}

public class B extends A{
public B(){}
}

public class C extends B{
public C(){} // <- error happens here
}
}

I get the following error:
"A.java": cannot reference this before supertype constructor has been
called at line 9, column 19

Is valid Java code/class structuring?

Thanks in advance for any help!
Your problem is that C cannot instantiate a B. Make B static and it
compiles, though I don't know that you're able to instantiate a C.
Alternately, provide an explicit call to a superconstructor in C's
constructor:
new A().super();

However, I'd suggest you take a second look at your design if you actually
think you need to do this.
 
C

Chris Uppal

Eric said:
public class A {
public A() {}

public class B extends A{
public B(){}
}

public class C extends B{
public C(){} // <- error happens here
}
}

I suspect that it's a bug in the compiler.

All the following is using JDK 1.5.0.

The compiler ought to treat the above as if it said (roughly):

public class A
{
public A() {}
}

class B extends A
{
private final A m_outer;
public B(A theA)
{
super();
m_outer = theA;
}
}

class C extends B
{
private final A m_outer;
public C(A theA)
{
super(theA);
m_outer = theA;
}
}

(but with B and C called "A$B" and "A$C" respectively). And that does compile
OK.

There is a problem with that, however, which is that if the compiler generated
code exactly like the above, methods called by A.B's constructor that had been
overridden in A,C would "see" A.B.m_outer with the wrong value (null), which is
illegal according to the Java spec (a bug in the language design if you ask me,
but there it is). So what the compiler actually wants to generate is more
like:

class B extends A
{
private final A m_outer;
public B(A theA)
{
m_outer = theA;
super();
}
}

class C extends B
{
private final A m_outer;
public C(A theA)
{
m_outer = theA;
super(theA);
}
}

The difference is that the assignment to m_outer is placed /before/ the call to
the superclass constructor. Doing that explicitly in Java would be illegal,
but the compiler allows itself to break its own rules (a sign of just how slimy
this hack is), and there's also a special hack in the verifier to allow the
corresponding bytecode sequence, which would otherwise be illegal. (And BTW,
if you compile for an early enough JVM, -target 1.2, say -- before the change
to the verifier, then javac will produce different code that puts the
assignment after the superclass constructor.)

It seems that the compiler will allow itself to generate the code for A.B's
hacky constructor, but not the very similar code for A.C. That /might/ be by
design, but I suspect not. Principally because if you remove the declaration
that A.B is a subclass of A, then it all works as you'd expect. There's no
obvious reason why making A.B a subclass of A should be /intended/ to interact
with the complicated hack, so I suspect it's just a bug.

BTW, if I create the bytecodes directly that I think the compiler /should/ be
generating, then the resulting classfile runs fine, so the JVM verifier is
happy enough with this situation. Another reason to suspect that its a bug in
the compiler.

-- chris
 
M

Mike Schilling

Eric said:
I have the following nested class structure:

public class A {
public A() {}

public class B extends A{
public B(){}
}

public class C extends B{
public C(){} // <- error happens here
}
}

I get the following error:
"A.java": cannot reference this before supertype constructor has been
called at line 9, column 19

Is valid Java code/class structuring?

Thanks in advance for any help!


What are you trying to accomplish? It seems unlikely that you need B both
to be a subclas of A and to have a containing instance of type A. (Likewise
for B and C.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top