File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Constructors Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Constructors" Watch "Constructors" New topic
Author

Constructors

sanjana narayanan
Ranch Hand

Joined: Nov 25, 2003
Posts: 142
i do not understand the following code
class Top {
int x;
class Dummy {
Dummy(Object o) {}
}
class Inside extends Dummy {
Inside() {
super(new Object() { int r = x; }); //1
}
Inside(final int y) {
super(new Object() { int r = y; }); }
}
}
Please explain to me exactly what is happening and how it can be resolved?
There is a compile error at line 1.
-Sanjana
Vad Fogel
Ranch Hand

Joined: Aug 25, 2003
Posts: 504
Very good and tricky question.

The error I'm getting is "cannot reference x before supertype constructor has been called". OK, the rule of thumb for making calls to super() and this() is that you cannot supply instance members as arguments to these calls because, well, the constructor hasn't completed constructing the object yet. However, in this example, class Inside is clearly an inner class, so by the time its instance gets created, the enclosing instance must exist on the heap, and x must be initialized! I'd love to hear the opinion of somebody who knows the compiler behavior whether it's a compiler issue or a JLS limitation.
Steven Broadbent
Ranch Hand

Joined: Dec 10, 2002
Posts: 400
Does it hinge on the fact that the super class here is also the enclosing class but compiler cannot determine that?.
Often that would not be the case, so members would not be access unitl after constructor had ran.
The order of creation etc is spelled out on page 314 of Sierra and Bates.


"....bigmouth strikes again, and I've got no right to take my place with the human race...."<p>SCJP 1.4
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Hi Sanjana, let's learn from something that compiles. I am going to move the anonymous class declaration.

Four class files are created.
Top$1.class, Top$Dummy.class, Top$Inside.class, Top.class
Let's disassemble the class files of Inside and the anonymous class:

Notice that the compiler adds a synthetic field this$1 to the anonymous class. It is a reference to the enclosing instance of Inside.
Notice that the compiler adds a synthetic field this$0 to the inner class Inside. It is a reference to the enclosing instance of Top.

When the anonymous subclass is instantiated, the instance variable r is initialized with x: First a reference to the anonymous object is loaded. Using that reference, the reference, this$1, to the Inside object is loaded. this$1 is passed to a static method of Inside and a reference to the Top object is returned. Using that reference, the value of x is loaded and stored in r.
Therefore, a reference to the Inside object and a reference to the Top object must be know when r is initialized to x. That is, the instance fields this$1 and this$0 must be initialized.
---
Now let's go back to your original example.
super(new Object() { int r = x; }); //1
The parameter list of the super(...) expression is called a static context. "this" cannot be used here. The instance variables of the Inside object have not been initialized. In particular, the instance field this$1 has not been initialized.
[ December 05, 2003: Message edited by: Marlene Miller ]
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Now I will try to state simply what is happening.
An inner class can access instance variables of the directly enclosing instance only if it has a compiler-generated reference to the enclosing instance.
If an inner class is declared in a static context, it has no reference to the directly enclosing instance.
[ December 05, 2003: Message edited by: Marlene Miller ]
sanjana narayanan
Ranch Hand

Joined: Nov 25, 2003
Posts: 142
Thank u so much..The explanation is too good..

-Sanjana
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
I learned about inner classes from Cay Horstmann's Core Java. He showed me how to disassemble a class file and what it means.
When I want to understand things about inner classes, and the JLS and The Java Programming Language just say the rules but not why, I almost always have to disassemble the class file.
javap -private Outer.class
javap -private Outer$Inner.class
javap -private Outer$1.class
You can see the extra fields the compiler adds. One object might have a reference to the other one. Or the local variables of one object might be copied to the other object. Or the constructor might have extra params. Think about two objects separated physically in space. It begins to make sense.
[ December 05, 2003: Message edited by: Marlene Miller ]
 
jQuery in Action, 2nd edition
 
subject: Constructors