繁体   English   中英

Stack Overflow java

[英]Stack Overflow java

作为类变量的对象会导致堆栈溢出

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对象变量时才说。 它会再次实际调用该类,这也应该导致无限循环。 在某个地方我错了。 有人可以突出我错在哪里。

不,将其声明为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类的实例,该构造函数又创建另一个,然后另一个,......然后它继续,导致堆栈溢出。

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

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

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

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

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

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

当JVM第一次捕获类时,静态变量将分配给内存

不完全是。

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

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

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

不,这有两个原因:

  • 通常,对象不是“实习”。 Interning是对String对象的操作,即使这样,它也只对String文字自动发生。 如果应用程序在其上显式调用String.intern()则非文字String对象只会被实现。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM