开发者

Why do I get StackOverflowError here?

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开发者_StackOverflow中文版 class SomeClass<T extends SomeClass> {

    SomeClass() {
        new SomeClassKiller();
    }

    private class SomeClassKiller extends SomeClass<T> {
    }

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


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!


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


This is because of the Recursive constructor calls happening between the classes SomeClass and 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.


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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜