• 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:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Access to "hidden" outer variables

 
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone,
I just was wandering whether it was possible to access an outer member variable from an Inner class that has another member variable with the same name.
For example, could we access the outer variable "var" from the Inner constructor in the code below?
My guess is that we cannot, but not 100% sure...
Any comments on this will be appreciated.
Thanks
Eduard
 
Ranch Hand
Posts: 295
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Yes you can.
Try this:
System.out.println (Outer.this.var);

Clement
 
Eduard Manas
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Clement,
Thanks for the trick (it works!)
I wouldn't have imagined that class names had variables/members. I have been reading through the java spec but I haven't found anything regarding to this.
Do you know of any other variables/members of class names? (just pure curiosity as I don't think it is part of the exam)
Eduard
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hope this helps:
 
Eduard Manas
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Jose,
Your code has clarified a lot of the questions I had about this issue.
I also added the line
"System.out.println(InnerSon.super.field);//1"
to the "printFields()" function and as expected it printed out a "1"
So it seems as if each class had two static private variables "this" and "super" that can only be accessed from an enclosing class (either the same class or an inner class).
Can anyone confirm this? Does anyone knows where this special behaviour is defined in the Java spec (if it is at all!)?
Thanks
Eduard
PS: Jose, I tried to run your code "as it is" but it gave me the following compile error in line "System.out.println(field);//1": -->field is inherited from Test.Inner and hides variable in outer class Test. An explicit 'this' qualifier must be used to select the desired instance<--
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


The keyword this can be qualified, to select one of possibly several current instances. (Inner classes have two or more current instances.)
PrimaryNoNewArray:
...
ClassName . this


This is from inner classes specification that I recommend you to read.
Thus who are the possible several current instances? just print to see them:

There are an instance of the inner class and an instance of the containing class, they are the instances created in main.
The notation "ClassName.this.field" can be used to access a field of any enclosing instance. A class is also considered as enclosing of itself, that is why InnerSon.this.field is accepted by the compiler.
Now from the same source as before


Any inherited member m of a subclass C is in scope within the body of C, including any inner classes within C. If C itself is an inner class, there may be definitions of the same kind (variable, method, or type) for m in enclosing scopes. (The scopes may be blocks, classes, or packages.) In all such cases, the inherited member m hides the other definitions of m.


In our example the field declared in Inner hides the one declared in Test.
Consider the following class within Test

Within Inner2, both "Inner2.this.field" and "this.field" access the field declared in Inner2 and the inherited ones, but not the fields declared in a containig scope (field in Test). That is why here they produce a compiler error. Note however the expressions "InnerSon.this.field" and "this.field" within InnerSon don't produce an error because they access the field inherited by Inner; otherwise they would give error because no field is declared within InnerSon.
The expression "field" within an inner class can access the fieldss declared in the class itself, those inherited, and the fields declared in a containig scope. However the inner classes specification adds:


Additionally, unless the hidden definition is a package member, the simple name m is illegal; the programmer must write C.this.m.


That is the error you get. It seems that the SDK 1.4 doesn't follow the spec in this point. Because I don't obtain that error. I guess you are not using SDK 1.4
 
Eduard Manas
Ranch Hand
Posts: 69
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well done Jose!, you resolved the "mistery" of the hidden outer variables
I now have a much better idea about inner classes.
What it has really surprised me is that the Inner Classes spec is kept in a different document than the java spec. I would have imagined that the java spec should be a complete and stand-alone document, and this proves it is not.
Thanks
Eduard
PS: you were right, I use JDK 1.3.1 noy JDK 1.4
 
reply
    Bookmark Topic Watch Topic
  • New Topic