作为类变量的对象导致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
对象变量时才说第一次。它会再次实际调用该类,这也应该导致无限循环。在某个地方我错了。有人可以突出我错在哪里。
答案 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只是忽略变量作为实例,它纯粹假设为静态,程序继续。