Java:StackOverflowError

时间:2013-10-24 07:30:08

标签: java

我正在研究Inner Class概念并编写以下代码_

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

我想知道当我取消注释第29行StackOverflowError为什么会line-29出现。同样在main方法中工作的地方。

  

有人可以帮助我,我错了或者背后有什么概念吗?

5 个答案:

答案 0 :(得分:5)

当创建InnerA的实例时,变量x会被初始化,从而导致InnerA被创建而另一个x被初始化,等等。

因此StackOverflowError

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

StackoverFlowError的堆栈跟踪中,您应该看到InnerA的构造函数一次又一次地被调用。

像这样的东西

at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31)
at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31)
at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31)

答案 1 :(得分:5)

让我们让这个例子更简单一点来解释会发生什么:

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

创建新的Example对象时会发生什么?

创建新对象,然后初始化其成员变量。类Example的成员变量为Example。因此,要初始化成员变量,将创建一个新的Example对象。那个又有一个需要初始化的Example类型的成员变量。因此,再次创建一个新的Example对象。而且那个又有一个需要初始化的Example成员变量。这种情况永远存在。

你有一个无限的递归循环,导致StackOverflowError

当您取消注释第29行时,您的班级InnerA中的内容完全相同:成员变量x使用新的InnerA进行初始化,该InnerA有自己的成员变量已初始化使用新的{{1}}等

答案 2 :(得分:0)

该行

int x = new InnerClassConcepts().new InnerA().new InnerB().x;
每次创建InnerA的新实例时都会执行

。由于此行创建了InnerA的另一个实例,因此将一次又一次地调用它。

答案 3 :(得分:0)

您正在通过创建新的InnerA实例初始化x的成员InnerA。所以这永远不会结束:)

答案 4 :(得分:-2)

内部类应该是静态的。或者每个实例需要一个新的类声明吗?

请参阅此答案以解释原因:whats-the-advantage-of-making-an-inner-class-as-static-with-java

另请参阅此findbugs错误说明:finbugs: inner class should be static

如果你要使你的内部类静态,你可以看到它没有按你编写它的方式编译。