1

我正在研究内部类概念并编写以下代码_

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

我想知道为什么当我取消注释line-29StackOverflowError时会出现。在方法上也是如此。line-29main

有人可以帮助我哪里错了或者这背后的概念是什么?

4

5 回答 5

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)
于 2013-10-24T07:32:26.350 回答
5

让我们把这个例子简单一点,来解释发生了什么:

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

当你创建一个新Example对象时会发生什么?

创建新对象,然后初始化其成员变量。类Example有一个成员变量,它是一个Example. 因此,为了初始化成员变量,Example创建了一个新对象。该变量又具有Example需要初始化的类型的成员变量。因此,再次创建了一个新Example对象。还有一个Example需要初始化的成员变量。这种情况永远持续下去。

你在那里有一个无限的递归循环,这导致StackOverflowError.

InnerA当您取消注释第 29 行时,您的类中有完全相同的东西:成员变量x用 new 初始化InnerA,它有自己的成员变量用 new 初始化InnerA,等等。

于 2013-10-24T07:36:55.917 回答
0

线

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

每次创建InnerA. 由于这一行创建了另一个实例,InnerA它将被一次又一次地调用..

于 2013-10-24T07:33:34.433 回答
0

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

于 2013-10-24T07:35:04.470 回答
-2

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

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

另请参阅此 findbugs 错误描述:finbugs:内部类应该是静态的

如果您将内部类设为静态,您会发现它不会按照您编写的方式进行编译。

于 2013-10-24T07:32:23.303 回答