Question about extending inner class

V

vahan

We have some simple code(Bruce Eckel's book):

class WithInner {
class Inner {}
}

public class InheritInner
extends WithInner.Inner {
//! InheritInner() {} //DON' T compile

InheritInner(WithInner wi) {
wi.super(); // is OK
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}

question is following :
Why does it call "wi.super();", as I understand WithInner's super
class constructor?
Thanks
 
D

danharrisandrews

Hi Vahan,

Unless an inner class is defined as static then it can not be created
outside of the context of an enclosing class instance. I'm looking at
the syntax of your example and it does look strange. Remember an inner
class will have access to its enclosing classes methods and members so
it makes perfect sense that you can not create an inner class outside
the context of an enclosing class instance. Also consider this strange
looking syntax. Hope that sheds some light.

public class Outer{

public class Inner{
}

public static void main(String[] args){
Outer.Inner inner = new Outer().new Inner();
}

}

Cheers,

Dan Andrews

- - - - - - - - - - - - - - - - - - - - - - - -
Ansir Development Limited www.ansir.ca
- - - - - - - - - - - - - - - - - - - - - - - -
 
P

Patricia Shanahan

vahan said:
We have some simple code(Bruce Eckel's book):

class WithInner {
class Inner {}
}

public class InheritInner
extends WithInner.Inner {
//! InheritInner() {} //DON' T compile

InheritInner(WithInner wi) {
wi.super(); // is OK
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}

question is following :
Why does it call "wi.super();", as I understand WithInner's super
class constructor?
Thanks

It is calling the WithInner.Inner constructor, the constructor for the
immediate super class of InheritInner.

However, because WithInner.Inner is an inner class, instances of it, and
its subclasses, cannot exist without a specified instance of WithInner
as surrounding object.

The qualified super class constructor call, wi.super(), specifies the
instance of WithInner referenced by wi as the surrounding WithInner object.

See the JLS, "8.8.5.1 Explicit Constructor Invocations",
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#229267
especially "Qualified superclass constructor invocations".

Patricia
 
V

vahan

Hi Dan, many thanks qualified answer


Hi Vahan,

Unless an inner class is defined as static then it can not be created
outside of the context of an enclosing class instance. I'm looking at
the syntax of your example and it does look strange. Remember an inner
class will have access to its enclosing classes methods and members so
it makes perfect sense that you can not create an inner class outside
the context of an enclosing class instance. Also consider this strange
looking syntax. Hope that sheds some light.

public class Outer{

public class Inner{
}

public static void main(String[] args){
Outer.Inner inner = new Outer().new Inner();
}

}

Cheers,

Dan Andrews

- - - - - - - - - - - - - - - - - - - - - - - -
Ansir Development Limited www.ansir.ca
- - - - - - - - - - - - - - - - - - - - - - - -

We have some simple code(Bruce Eckel's book):

class WithInner {
class Inner {}
}

public class InheritInner
extends WithInner.Inner {
//! InheritInner() {} //DON' T compile

InheritInner(WithInner wi) {
wi.super(); // is OK
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}

question is following :
Why does it call "wi.super();", as I understand WithInner's super
class constructor?
Thanks
 
V

vahan

Hi Dan, many thanks qualified answer


Hi Vahan,

Unless an inner class is defined as static then it can not be created
outside of the context of an enclosing class instance. I'm looking at
the syntax of your example and it does look strange. Remember an inner
class will have access to its enclosing classes methods and members so
it makes perfect sense that you can not create an inner class outside
the context of an enclosing class instance. Also consider this strange
looking syntax. Hope that sheds some light.

public class Outer{

public class Inner{
}

public static void main(String[] args){
Outer.Inner inner = new Outer().new Inner();
}

}

Cheers,

Dan Andrews

- - - - - - - - - - - - - - - - - - - - - - - -
Ansir Development Limited www.ansir.ca
- - - - - - - - - - - - - - - - - - - - - - - -

We have some simple code(Bruce Eckel's book):

class WithInner {
class Inner {}
}

public class InheritInner
extends WithInner.Inner {
//! InheritInner() {} //DON' T compile

InheritInner(WithInner wi) {
wi.super(); // is OK
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}

question is following :
Why does it call "wi.super();", as I understand WithInner's super
class constructor?
Thanks
 
C

Chris Uppal

Patricia said:
The qualified super class constructor call, wi.super(), specifies the
instance of WithInner referenced by wi as the surrounding WithInner
object.

See the JLS, "8.8.5.1 Explicit Constructor Invocations",
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#229267
especially "Qualified superclass constructor invocations".

It's really weird syntax, though. To my mind:

InheritInner(WithInner wi)
{
wi.super();
}

would be a lot more sensible. Just as (some helper method outside WithInner):

static WithInner.Inner
makeInner(WithInner wi)
{
return new WithInner.Inner(wi);
}

makes more sense to me than:

static WithInner.Inner
makeInner(WithInner wi)
{
return wi.new Inner();
}

The JLS syntax is obfuscatory, but doesn't actually achieve what (I presume) it
is intended to do -- namely protecting programmers from the need to know how
this garbage is implemented.

BTW, disassembling the "correct" constructor gives:

<init> (LWithInner;)V
aload_0
aload_1
dup
invokevirtual java/lang/Object/getClass ()Ljava/lang/Class;
pop
invokespecial WithInner$Inner/<init> (LWithInner;)V
return

Does anyone know what the call to java.lang.Object.getClass() is intended to
achieve ? It's applied to the "wi" parameter, but then the returned value is
discarded. Exactly the same apparently superfluous call is generated for my
helper method, above. The only thing I can think of is that it's a rather odd
way of doing a not-null test.

-- chris
 
P

Patricia Shanahan

Chris Uppal wrote:
.....
Does anyone know what the call to java.lang.Object.getClass() is intended to
achieve ? It's applied to the "wi" parameter, but then the returned value is
discarded. Exactly the same apparently superfluous call is generated for my
helper method, above. The only thing I can think of is that it's a rather odd
way of doing a not-null test.
....

Alternatively, perhaps it is a way of forcing class loading???

Patricia
 
C

Chris Uppal

Patricia Shanahan wrote:

[me:]
...

Alternatively, perhaps it is a way of forcing class loading???

I can't see it. After all, the class of the parameter object must have been
loaded already (if it's not null) or it couldn't exist. OTOH, if the parameter
/is/ null then getClass() won't load anything...

I wondered if the verifyer would refuse the equivalent of:

InheritInner(WithInner wi)
{
if (wi == null)
throw new NullPointerException("Ooops!");
wi.super();
}

(which is illegal Java of course), but if I create the corresponding bytecodes
directly then the JVM seems perfectly happy to load the class. Ho hum...

-- chris
 
P

Patricia Shanahan

Chris said:
Patricia Shanahan wrote:

[me:]
...

Alternatively, perhaps it is a way of forcing class loading???

I can't see it. After all, the class of the parameter object must have been
loaded already (if it's not null) or it couldn't exist. OTOH, if the parameter
/is/ null then getClass() won't load anything...

Good point.

Patricia
 

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

Forum statistics

Threads
474,264
Messages
2,571,065
Members
48,770
Latest member
ElysaD

Latest Threads

Top