1

I am working on Inner Class concepts and write the below code_

public class InnerClassConcepts {
private int x = 11;

public static void main(String... args) {
    // method local 'x' variable
    int x = new InnerClassConcepts().new InnerA().new InnerB().x;

    InnerClassConcepts in = new InnerClassConcepts();
    InnerA InnerA = in.new InnerA();
    InnerA.InnerB xx = in.new InnerA().new InnerB();

    System.out.println("InnerClassConcepts`s x = " + in.x);
    System.out.println("InnerB`s x = " + xx.x);
    System.out.println("main`s x(local variable) = " + x);
    // System.out.println("InnerA`s x = " + InnerA.x);
    System.out.println("InnerA`s y = " + InnerA.y);
}

/**
 * Local inner class.
 */
class InnerA {
    int y = 10;

    /*
     * java.lang.StackOverflowError coming over here... I don`t
     * understand why?
     */
    // int x=new InnerClassConcepts().new InnerA().new InnerB().x;//Line-29
    /**
     * Inner class inside an another Inner class.
     */
    class InnerB {
        private int x = 22;
        int z = InnerA.this.y;

    }

 }
}

Output_

InnerClassConcepts's x = 11
InnerB's x = 22
main's x(local variable) = 22
InnerA's y = 10

I am wondering why StackOverflowError is coming on line-29 when i uncomment line-29. Where as the same is working in main method.

Can somebody please help me where i am wrong or what concept is behind this?

Rupesh Yadav
  • 12,096
  • 4
  • 53
  • 70

5 Answers5

5

When an instance of InnerA is created the variable x gets initialized which causes an InnerA to be created and another x gets initialized and so on.

Thus the StackOverflowError

// int x=new InnerClassConcepts().new InnerA().new InnerB().x;//Line-29

In the stack trace of the StackoverFlowError you should see that the Constructor of InnerA is invoked again and again.

Something like this

at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31)
at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31)
at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31)
René Link
  • 48,224
  • 13
  • 108
  • 140
5

Let's make the example a bit simpler, to explain what happens:

class Example {
    private Example example = new Example();
}

What happens when you create a new Example object?

The new object is created, and then its member variables are initialized. Class Example has a member variable that is an Example. So, to initialize the member variable, a new Example object is created. That one in turn has a member variable of type Example that needs to be initialized. So, again a new Example object is created. And that one again has an Example member variable that needs to be initialized. This goes on forever.

You have an infinite recursive cycle there, which leads to a StackOverflowError.

You have exactly the same thing in your class InnerA when you uncomment line 29: member variable x is initialized with a new InnerA, which has its own member variable that is initialized with a new InnerA, etc.

Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 1
    It sounds like the guy who, yesterday, wondered why the class String embed an array of char and not a String ^^ – Julien Oct 24 '13 at 07:46
0

The line

int x = new InnerClassConcepts().new InnerA().new InnerB().x;

is executed every time you create a new instance of InnerA. Since this line creates another instances of InnerA it will be called again and again..

micha
  • 47,774
  • 16
  • 73
  • 80
0

You are initializing InnerA's member x by creating a new InnerA instance. So this will never end :)

Matthias
  • 3,582
  • 2
  • 30
  • 41
-2

Inner classes should be static. Or do you need a new class declaration per instance?

See this answer to explain why: whats-the-advantage-of-making-an-inner-class-as-static-with-java

Also see this findbugs bug description: finbugs: inner class should be static

If you would make your inner classes static you could see that it doesn't compile the way you wrote it.

Community
  • 1
  • 1
mwhs
  • 5,878
  • 2
  • 28
  • 34
  • where does it say that they should be static? Non-static nested classes are by definition called inner classes. Please do your research before posting "answers". – Wim Ombelets Oct 24 '13 at 07:35
  • @WimOmbelets A lot of people say that. There is even a findbugs rule for that. See this thread: [whats-the-advantage-of-making-an-inner-class-as-static-with-java](http://stackoverflow.com/questions/16147405/whats-the-advantage-of-making-an-inner-class-as-static-with-java) – mwhs Oct 24 '13 at 07:41
  • 1
    there is a distinct difference between a possible advantage of rendering a class static and implying to the OP that it _should_ be static. Either way, your answer does not address the problem at hand. – Wim Ombelets Oct 24 '13 at 07:44
  • @WimOmbelets I'm sorry, but the fact that the inner classes are _not_ static exactly adresses the problem at hand. If he would have made the inner classes static the problematic line `int x = new InnerClassConcepts().new InnerA().new InnerB().x;` wouldn't even compile. This would show Rupesh that there is something wrong with the instantiation of his object tree and he could fix it directly there. Your proposal to fix his problem is to remove some code. In how far is that a better solution? – mwhs Oct 24 '13 at 07:55