为什么我会在这里收到 StackOverflowError?

发布于 2024-10-08 06:10:19 字数 369 浏览 5 评论 0原文

为什么这段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();
    }
}

Why does this java code produce StackOverflowError? I understand that this somehow connected with recursive generic type parameter. But I don't understand clear the whole mechanism.

public class SomeClass<T extends SomeClass> {

    SomeClass() {
        new SomeClassKiller();
    }

    private class SomeClassKiller extends SomeClass<T> {
    }

    public static void main(String[] args) {
        new SomeClass();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

七堇年 2024-10-15 06:10:19

通用部分并不重要——类的嵌套也并不重要。看看这对几乎等价的类,它应该更明显:

public class SuperClass
{
    public SuperClass()
    {
        new SubClass();
    }
}

public class SubClass extends SuperClass
{
    public SubClass()
    {
        super();
    }
}

所以子类构造函数调用超类构造函数 - 然后创建一个新的子类,它调用超类构造函数,它创建一个新的子类,等等...... !

The generic part doesn't matter - nor does it really matter that the class is nested. Look at this mostly-equivalent pair of classes and it should be more obvious:

public class SuperClass
{
    public SuperClass()
    {
        new SubClass();
    }
}

public class SubClass extends SuperClass
{
    public SubClass()
    {
        super();
    }
}

So the subclass constructor calls the superclass constructor - which then creates a new subclass, which calls into the superclass constructor, which creates a new subclass, etc... bang!

沉溺在你眼里的海 2024-10-15 06:10:19

这里它从另一个构造函数调用一个构造函数,并从中调用前一个构造函数,循环构造函数链,请参阅下面的注释

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
    }
}

Here it is invoking one constructor from another and from it the previous one, cyclic constructor chain, see the comments below

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
    }
}
恋竹姑娘 2024-10-15 06:10:19

这是因为类 SomeClass 和类之间发生了递归构造函数调用
某类杀手。

This is because of the Recursive constructor calls happening between the classes SomeClass and
SomeClassKiller.

未央 2024-10-15 06:10:19
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 。

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();
    }
}

The code produced by the compiler is something like this, so when u create an object it recursivly calls the SomeClass and SomeClassKiller for ever.

╰沐子 2024-10-15 06:10:19

构造函数是从上到下调用​​的,也就是说,如果类 A 派生自 B,A 的构造函数将首先调用父构造函数 (B )。

在你的例子中,new SomeClassKiller() 递归地调用 SomeClass 的构造函数,而该构造函数又构造了另一个 SomeClassKiller ……就是这样。

Constructors are invoked top-to-bottom, that is if a class A derives from B, A's constructors will first invoke the parent constructor (B).

In you case, new SomeClassKiller() recursively calls the constructor of SomeClass which in turn constructs another SomeClassKiller … there it is.

就是爱搞怪 2024-10-15 06:10:19

main() 方法正在创建 SomeClass 的新实例,该实例调用创建新实例的 SomeClass 构造函数默认情况下,SomeClassKiller 调用父构造函数并发生堆栈溢出。

避免堆栈溢出。将代码更改为如下所示:

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();
    }
}

The main() method is creating a new instance of SomeClass which calls the SomeClass constructor that creates a new instance of SomeClassKiller that by default calls the parent constructor and the stackoverflow occurs.

To avoid the stackoverflow. Change the code to look as follows:

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文