• 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

Nested Classes

 
Ranch Hand
Posts: 4716
9
Scala Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
when declaring and innitializing an inner class object from an outside class, we say this:
Outer.Inner x = new Outer().new Inner();
however if we are instantiating it inside Outer we can say:
Inner x = new Outer().new Inner();
Is that correct?
can we also say:
Inner x = this.new Inner();
Is that correct?
I find Inner classes the hardest topic.
 
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Randall,
I agree with you that inner classes are a topic which needs to be dug deep.
I think both of the things you have said will work. However, it will be better if we try it with a program.

------------------
Regards,
Shree
 
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Take the following example:
<pre>class Outer {
class Inner{}
public static void main(String[] args) {
Inner a = new Outer().new Inner();
Outer.Inner f = new Outer().new Inner();
}
public void method() {
Inner b = new Inner();
Inner c = this.new Inner();
Outer.Inner d = new Inner();
Outer.Inner e = new Outer().new Inner();
}
}
public class Separate {
public static void main(String[] args) {
Outer.Inner b = new Outer().new Inner();
/** Inner g = new Outer().new Inner(); // this is invalid */
}
}
</pre>
Answer depends on where you're trying to create the inner class. The above code demonstrate some of the valid construction calls.
 
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Randall,
Just to note, Inner x = this.new Inner(); will not compile.
Cheers,
Brian C
 
Brian, Cavanagh
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with Sam,
Inner x = this.new Inner(); will not compile from the main() method.
 
Sam Wong
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For static methods, this and super doesn't apply hence this.new Inner() won't work.
 
Brian, Cavanagh
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually on trying some out some code Sam,
I cannot get Inner i = this.new.Inner(); to compile
yet, your code seems to compile fine. I am calling this line of code in a method of the outer class. Confused confused:
 
Sam Wong
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Post your code and let's see what's happening.
Inner i = this.new.Inner() won't compile anywhere. wrong usage of new keyword.
[This message has been edited by Sam Wong (edited December 14, 2000).]
 
Brian, Cavanagh
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmm, in your code though, you use Inner c = this.new Inner();
Anyway, here's the code, see what you can make of it. Thanks in advance.
public class InnerTest
{
static int staticTestVar = 12;
final static String m = "M!!";
static int me = 3;
int test = InnerTest.this.me;
class InnerClass
{
String twoMs = m + m;
int x = me;
int y = InnerTest.this.me;
int z = test;
public String write(String str)
{
System.out.println("" + str);
z = x + me + staticTestVar;
return str;
}
} // end of inner class
public void mTest()
{
InnerClass ite = new InnerClass();
InnerClass i = this.new.InnerClass(); // Sam, this line fails
}
public static void main(String args[])
{
InnerTest out = new InnerTest();
InnerClass out2 = new InnerTest().new InnerClass();
InnerTest.InnerClass in =
new InnerTest().new InnerClass();
InnerTest.InnerClass in2 =
new InnerTest().new InnerClass();
InnerTest.InnerClass in3 =
new InnerTest().new InnerClass();
}
}
 
Sam Wong
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Line in question:
InnerClass i = this.new.InnerClass(); // Sam, this line fails

Brian, tell me what you see after the "new" word? If you see the period, then its why it won't compile. Probably an oversight on your part.
My code uses InnerClass i = this.new InnerClass();
In accordance to proper usage of the keyword "new".
 
shree vijay
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Sam Wong:
Take the following example:
<pre>class Outer {
class Inner{}
public static void main(String[] args) {
Inner a = new Outer().new Inner(); //1
Outer.Inner f = new Outer().new Inner();
}
public void method() {
Inner b = new Inner();
Inner c = this.new Inner();
Outer.Inner d = new Inner(); //2
Outer.Inner e = new Outer().new Inner(); //3
}
}
public class Separate {
public static void main(String[] args) {
Outer.Inner b = new Outer().new Inner();
/** Inner g = new Outer().new Inner(); // this is invalid */
}
}
</pre>
Answer depends on where you're trying to create the inner class. The above code demonstrate some of the valid construction calls.



Hi,
I compiled the above thing and it works fine. It was very useful and i tried to form some generic rules regarding all the possible combinations
Rule 1: In a separate class (not in outer class), the only possible way is
Outer.Inner i = new Outer().new Inner()
We are talking about non-static inner classes.
Rule 2: In any method of Outer other than main, all combinations are possible.
The simplest is Inner i = new Inner()
Rule 3: In main, there cannot be any reference to this or super, therefore, main has to know the Class type.
Now, my doubts,
1.In the context of rule 3, isn't line marked //1 an error?

Inner a = new Outer().new Inner();
How does main get to know that reference a is indeed an inner class from Inner a? This cannot mean this.Inner a = new Outer().new Inner
2. Are statements //2 and //3 the same?
Outer.Inner d = new Inner(); //2
Outer.Inner e = new Outer().new Inner(); //3
The second one creates an Outer() instance but the first one does not.

------------------
Regards,
Shree
 
Sam Wong
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now, my doubts,
1.In the context of rule 3, isn't line marked //1 an error?

Inner a = new Outer().new Inner();
It is valid because this static method resides in the enclosing class. So it doesn't have to reference the full namespace. It knows about Inner. Similar to the fact that you don't need to import other classes in your own package to reference them without the full package name.
How does main get to know that reference a is indeed an inner class from Inner a? This cannot mean this.Inner a = new Outer().new Inner
2. Are statements //2 and //3 the same?
Outer.Inner d = new Inner(); //2
Outer.Inner e = new Outer().new Inner(); //3
The second one creates an Outer() instance but the first one does not.
They aren't the same. 2 uses the "this" instance of Outer while 3 creates a new instance of Outer. The enclosing object are not equal.

 
Sam Wong
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Shree, your rules are almost correct.
Rule 1 is true unless you explicitly import the Inner class.
<pre>import Outer.Inner;
public class Thing {
Inner b = new Outer().new Inner();
}</pre>

Rule 2 should be changed to "In any instance method, all combinatiions are possible."
Rule 3 should be changed to "For static methods, there cannot be any reference to this or super, therefore, it has to know the Class type."
 
Brian, Cavanagh
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're absolutely right Sam. An complete oversight on my part.
Thanks again.
Brian
 
shree vijay
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Sam Wong:
Now, my doubts,
1.In the context of rule 3, isn't line marked //1 an error?

Inner a = new Outer().new Inner();
[b]It is valid because this static method resides in the enclosing class. So it doesn't have to reference the full namespace. It knows about Inner. Similar to the fact that you don't need to import other classes in your own package to reference them without the full package name.


[/B]


Hi,
I am clear now about the second one , but still not the first one
main is a static class. If i try to access , let us say, an instance int variable of the outer class with default access, it will give a compile time error saying a non-static variable cannot be accessed in a static method.
In the example Inner is a non-static class... wait i think i am getting confused all the more --

ok, my question is... how is it that there need not be any qualification like Outer.Inner a = new Outer().new Inner();
How can Outer.Inner a be replaced by Inner a, when main cannot 'know' a non-static member?
------------------
Regards,
Shree
 
Sam Wong
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's an example:
<pre>
public class Outer {
static int a = 1;
int b = 2;
class Inner {}
public static void method() {
System.out.println(a);
System.out.println(new Outer().b);
Inner c = new Outer().new Inner();
}
}</pre>
The inner class is just a member of the enclosing class just like the int variables. In this case, I decided not to use main because I think you're getting confused about main. Thus, I'm using a generic static method to illustrate. The static method can reference a and b. Though it requires an instance of Outer to reference b because its an instance variable. Same goes for class Inner. It is not declared as static. Therefore, you need an instance of Outer. This is not the confusion. You want to know why I can use Inner instead of Outer.Inner. Well, if you understand why I can reference the int a without using Outer.a, then the reason should become apparent. The method lives within the class Outer so it has inherent knowledge of the members. Same can't be said for other separate classes. Hope this helps.
 
shree vijay
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi ,

I really got it with that example. Thanks a ton. And those rules were also very good .

------------------
Regards,
Shree
 
Ranch Hand
Posts: 112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys,
Congrats for the solution that u have found. I would say that any new comer to java who is confused with inner classes should see this thread to clarify all his doubts about innner classes.I thought of giving my thoughts but the last two inputs from Sam wraps it up cleanly. The rules framed by Shree are pretty good i must say.
All the best for ur JCP preparation.
Rajesh
SCJP2
reply
    Bookmark Topic Watch Topic
  • New Topic