为什么这个java代码会产生StackOverflowError
?我知道这与递归泛型类型参数有某种联系。但我不明白整个机制。
public class SomeClass<T extends SomeClass> {
SomeClass() {
new SomeClassKiller();
}
private class SomeClassKiller extends SomeClass<T> {
}
public static void main(String[] args) {
new SomeClass();
}
}
答案 0 :(得分:13)
通用部分并不重要 - 类嵌套也不重要。看看这个大多数等同的类,它应该更明显:
public class SuperClass
{
public SuperClass()
{
new SubClass();
}
}
public class SubClass extends SuperClass
{
public SubClass()
{
super();
}
}
所以子类构造函数调用超类构造函数 - 然后创建一个新的子类,调用超类构造函数,创建一个新的子类,等等... bang!
答案 1 :(得分:2)
这里是从另一个构造函数中调用一个构造函数,并从前一个构造函数链调用,参见下面的注释
public class SomeClass<T extends SomeClass> {
SomeClass() {//A
new SomeClassKiller();// calls B
}
private class SomeClassKiller extends SomeClass<T> {//B
//calls A
}
public static void main(String[] args) {
new SomeClass(); //calls A
}
}
答案 2 :(得分:1)
这是因为SomeClass和类之间发生递归构造函数调用 SomeClassKiller。
答案 3 :(得分:0)
public class SomeClass<T extends SomeClass> {
SomeClass() {
new SomeClassKiller();
}
private class SomeClassKiller extends SomeClass<T> {
public SomeClassKiller()
{
super(); //calls the constructor of SomeClass
}
}
public static void main(String[] args) {
new SomeClass();
}
}
编译器生成的代码是这样的,所以当你创建一个对象时,它会递归地调用SomeClass和SomeClassKiller。
答案 4 :(得分:0)
从上到下调用构造函数,即如果类A
派生自B
,则A的构造函数将首先调用父构造函数(B
)。
在你的情况下,new SomeClassKiller()
以递归方式调用SomeClass
的构造函数,而构造函数又构造了另一个SomeClassKiller
......就在那里。
答案 5 :(得分:0)
main()
方法正在创建SomeClass
的新实例,该实例调用SomeClass
构造函数,创建SomeClassKiller
的新实例default调用父构造函数并发生stackoverflow。
避免堆栈溢出。将代码更改为如下所示:
public class SomeClass<T extends SomeClass> {
SomeClass() {
new SomeClassKiller();
}
private class SomeClassKiller extends SomeClass<T> {
public SomeClassKiller(){
//super(); does this by default, but is now commented out and won't be called.
}
}
public static void main(String[] args) {
new SomeClass();
}
}