Stack Overflow java

时间:2013-08-31 11:47:28

标签: java static

作为类变量的对象导致stackoverflow

public class stack {
        stack obj = new stack();   // its obvious that during class loading obj will call class to
        // load and infinite loop will occur. 
}

假设我在班级obj中使用static

public class stack {
      static stack obj = new stack();  // it will not cause infinite loop and program will //execute successfully
}

当JVM第一次捕获类时,静态变量被分配到内存中(据我所知)。 仅在JVM开始将内存分配给上述static对象变量时才说第一次。它会再次实际调用该类,这也应该导致无限循环。在某个地方我错了。有人可以突出我错在哪里。

5 个答案:

答案 0 :(得分:6)

不,将其声明为static不会导致无限循环。这就是原因。

静态变量在类加载时初始化。因此,当您的类第一次加载时,编译器将为静态变量创建一个实例,就是这样。这不会导致您的班级第二次加载。由于您的课程没有再次加载,因此不会重复此过程。

如果您将其声明为非静态属性,那么这是一个完全不同的故事。考虑一下 -

public class stack {
    stack obj = new stack();

    ........
}

此声明相当于 -

public class stack {
   stack obj;

    public stack() {
        obj = new stack();    // implicitly moved here by the compiler
    }

    ........
}

从最后一个例子可以看出为什么这里有无限递归。您正在自己的构造函数中创建stack类的实例,而后者又创建了另一个,然后是另一个......然后它继续,导致堆栈溢出。

答案 1 :(得分:0)

加载“stack”类将导致创建“stack”实例,将其保存为堆栈类的静态字段。然后,堆栈类的这个实例无需加载:没有堆栈异常。

答案 2 :(得分:0)

关键字Static与无限循环无关。您可以声明字段,方法,类(静态内部类)

静态字段: - 首次加载类时,会创建并初始化静态字段。当引用类的静态成员或创建类的实例时(以先到者为准),就会发生这种情况。

静态方法: - 使用static关键字声明的方法。与静态字段一样,静态方法与类本身相关联,而不是与从类创建的任何特定对象相关联。因此,在使用类定义的静态方法之前,不必从类创建对象。

最着名的静态方法是main,由Java运行时调用以启动应用程序。 main方法必须是静态的,这意味着默认情况下应用程序在静态上下文中运行。

内存透视: - 由于类被加载一次并且其定义存储在jvm的permgen区域中,因此静态变量也存储在那里,并且将存在于jvm的生命周期中。

答案 3 :(得分:0)

  

当JVM第一次捕获类时,静态变量被分配到内存中

不完全是。

加载类时会分配静态变量。

初始化类时执行静态变量初始化。这可能会在课程加载后的某个时间发生。

  

仅在JVM开始将内存分配给上述静态对象变量时才说第一次。它会再次实际调用该类,这也应该导致无限循环。

没有。这有两个原因:

  • 一般来说,对象不是“实习”。 Interning是对String个对象的操作,即使这样,它也只会自动为String文字。如果您的应用程序在其上明确地调用String.intern() ,则非文字String对象只会被实现。

  • 即使自动执行某种实习,也不会导致无限循环。您似乎认为实习会以某种方式导致类初始化重新启动或重复。这种情况不可能发生,JVM会花费相当长的时间来确保每个类在其生命周期内最多初始化

答案 4 :(得分:0)

在调试过程中,我们可以知道,当第一次控制到静态变量时, 因为变量只是类的一个实例,它将调用类加载。

然后控件进入类,并找到一个静态变量对象,但此时它将由JVM分配一个内存地址值(与其他静态变量一样)。 Control只是忽略变量作为实例,它纯粹假设为静态,程序继续。