我正在研究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
方法中工作的地方。
有人可以帮助我,我错了或者背后有什么概念吗?
答案 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
如果你要使你的内部类静态,你可以看到它没有按你编写它的方式编译。