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 Access to variables of enclosing class 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 "Access to variables of enclosing class" Watch "Access to variables of enclosing class" New topic
Author

Access to variables of enclosing class

Morten Monrad Pedersen
Ranch Hand

Joined: May 15, 2006
Posts: 31
Hi fellow ranchers

I would appreciate any explanations of why the code below can't compile:



For some reason the instance variable of Outer can't be accessed by the anonymous class, but I don't understand why this is so.
Petrus Pelser
Ranch Hand

Joined: Feb 20, 2006
Posts: 132
There is no variable named str in the class you are using it (UseOuter).

Change the line:


To:


You need to access str from the Outer class because str is not present in the Inner class.
Morten Monrad Pedersen
Ranch Hand

Joined: May 15, 2006
Posts: 31
Hi Petrus

Thank you for your answer.

You need to access str from the Outer class because str is not present in the Inner class.


If I change the println method of Inner to be

Then that method compiles just fine, so str is available in Inner, but not in the anonymous extension of Inner, and I don't understand, why this is so.
Petrus Pelser
Ranch Hand

Joined: Feb 20, 2006
Posts: 132
str is out of scope in the UseOuter class' main method.
Morten Monrad Pedersen
Ranch Hand

Joined: May 15, 2006
Posts: 31
Hi Petrus

Once again thank you for answering.

str is out of scope in the UseOuter class' main method.


But why is it the scope of UseOuter's main that determines whether str is accessible to the anonymous class? str is available to Inner and isn't declared private. Therefore it seems to me that str ought also be available to all the subclasses of Inner.

Perhaps I should rather phrase my question like this: Can you (or someone else) provide a good reason for why the creators of Java chose to make non-private variables that are available in a given class unavaible to it's subclasses?
Krishnamoorthy Sethuraman
Greenhorn

Joined: Dec 12, 2005
Posts: 24
yes, even if the inner class is extended as a named class and the outer class variable is declared public, I'm not able to access the outer class variables in the extended inner class. Is it a bug?
Krishnamoorthy Sethuraman
Greenhorn

Joined: Dec 12, 2005
Posts: 24
One more thing I found is that the enclosing class reference(Outer.this.str) is not available to the extended inner class(while it is available if referenced from within the inner class directly).
Petrus Pelser
Ranch Hand

Joined: Feb 20, 2006
Posts: 132
This is the best solution I can find:


Create a final object of Outer. Use that object to create a new Inner class and then also use the same Outer object to access the str String. The object has to be final because anonymous inner classes can only access final local variables.

Remember that str is not inherited by the Inner class or by the UseOuter class, so the variable str is not visible where the anonymous class is defined.

Hope this helps.
Petrus Pelser
Ranch Hand

Joined: Feb 20, 2006
Posts: 132
Here's another example:



The anonymous class now can access the str2 variable because it declared in the Inner class.

So it looks like anonymous inner classes does not have access to the enclosing class' members when defined outside the enclosing class.

Very confusing!
Morten Monrad Pedersen
Ranch Hand

Joined: May 15, 2006
Posts: 31
Thank you for the help everyone.

So it looks like anonymous inner classes does not have access to the enclosing class' members when defined outside the enclosing class.

Very confusing!


Yes, it's confusing, and that's why I hoped that someone could come up with a logical explanation .
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
A subclass can see only the members inherited from its superclasses. Outer.str is not a member of Outer.Inner because Inner does not extend Outer.


Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
Vladimir Scheglov
Greenhorn

Joined: Jun 19, 2006
Posts: 20
May be this code better:

class Outer {
String str = "Hello";

class Inner {
String getStr(){
return str;
}

void setStr(String value){
str = value;
}

public void println(){}
}
}

public class Test{

public static void main(String arg[]){
Outer.Inner inner = new Outer().new Inner() {
public void println()
{
System.out.println(getStr());
}
};
inner.println();
}
}
Morten Monrad Pedersen
Ranch Hand

Joined: May 15, 2006
Posts: 31
Thanks for the answer Barry.

Originally posted by Barry Gaunt:
A subclass can see only the members inherited from its superclasses. Outer.str is not a member of Outer.Inner because Inner does not extend Outer.


That's true, but it seems most consistent (to me at least), that when something non-private is accessible to a class then it should also be accessible to its subclasses.
Morten Monrad Pedersen
Ranch Hand

Joined: May 15, 2006
Posts: 31
Hi Vladimir

That's a nice solution .
Vladimir Scheglov
Greenhorn

Joined: Jun 19, 2006
Posts: 20
more better code:
class Outer {
String str = "Hello";

class Inner {
Outer outer = Outer.this;

public void println(){}
}
}

public class Test{

public static void main(String arg[]){
Outer.Inner inner = new Outer().new Inner() {
public void println(){
System.out.println(outer.str);
}
};
inner.println();
}
}
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Access to variables of enclosing class