• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Access to variables of enclosing class

 
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 132
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
str is out of scope in the UseOuter class' main method.
 
Morten Monrad Pedersen
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes, even if the inner class is extended as a named class and the outer class variable is declared coderanch, I'm not able to access the outer class variables in the extended inner class. Is it a bug?
 
Krishnamoorthy Sethuraman
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 132
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 132
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 .
 
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Vladimir

That's a nice solution .
 
Vladimir Scheglov
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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();
}
}
reply
    Bookmark Topic Watch Topic
  • New Topic