类的实例是如何递归创建的,从而导致stackoverflow错误

时间:2012-06-27 07:27:30

标签: java

考虑以下2个程序给出相同的错误
第一个问题:

public class Testing {    
    Testing t=new Testing();        
    public static void main(String args[]){   
        testing t1=new testing();  
    }
}

第二课:

class foo{
    void baz(){
        new testing();
    }
}
public class testing {
    testing t=new testing();    
    public static void main(String args[]){
    foo f=new foo();
        f.baz();
    }       
}

以上代码如何给出以下错误?
 我知道类的实例是递归创建但我想知道如何?

Exception in thread "main" java.lang.StackOverflowError
    at com.Testing.<init>(Testing.java:4)
    at com.Testing.<init>(Testing.java:4)

如果我们这样做,为什么不会发生这种情况

    public class testing { 
    testing t2=new testing(); 
    testing t1=new testing(); 
    public static void main(String args[])
    {//anything}
    }

因为t1将要求t2对象被初始化,反之亦然?

2 个答案:

答案 0 :(得分:7)

这是问题所在:

public class Testing {    
    Testing t=new Testing();  
}

这大致与:

相同
public class Testing {
    Testing t;

    public Testing() {
        t = new Testing();
    }
}

这使得递归更加清晰 - 构造函数无条件地调用自身。

Testing的每个实例都包含对另一个Testing实例的引用。 不需要成为问题 - 但它就在这里,因为它正在创建Testing实例。因此,创建“最外层”实例会立即触发另一个实例的创建...这将触发另一个实例的创建等。

您的两个类在这方面没有显着差异 - 创建Testing的任何实例都会导致堆栈溢出。

编辑:关于此代码(名称和格式改进):

public class Testing { 
    Testing t1 = new Testing(); 
    Testing t2 = new Testing(); 

    public static void main(String[] args) {
        //anything
    }
}
如果您尝试创建Testing的实例,

仍会抛出相同的异常。你说't1将需要t2对象进行初始化'是错误的 - 这里的变量之间没有相互依赖关系。每个变量初始值设定项都会创建一个单独的对象......但是每个那些对象都会尝试再创建两个Testing的实例。

请注意,为了运行Testing方法,main的实例不是 - 但如果main方法调用new Testing直接调用,或调用调用new Testing() else ,然后你就会得到堆栈溢出。

答案 1 :(得分:3)

曾经想过你的节目何时结束......永远不会。它实例化你的第一个对象,同时实例化它需要为第一个对象设置另一个对象,依此类推。所以你的筹码会在一段时间内爆发。

第一个对象(需要第二个对象(需要第三个对象(需要第四个对象)))并继续...