我创建一个类如下:
public class NodeOne {
NodeOne nodeone = new NodeOne();
public NodeOne() {
System.out.println("1");
}
public static void main(String[] args) {
NodeOne nodeone = new NodeOne();
}
}
一旦我运行它,我得到异常“线程中的异常”主“java.lang.StackOverflowError “,我知道确定的原因。但是当我在场节点之前添加修饰符”static“时,结果就好了。那么深层原因是什么?
public class NodeOne {
static NodeOne nodeone = new NodeOne();
public NodeOne() {
System.out.println("1");
}
public static void main(String[] args) {
NodeOne nodeone = new NodeOne();
}
}
输出:
1
1
答案 0 :(得分:2)
在第一种情况下,每次创建新对象NodeOne
时,其默认构造函数都会为其字段nodeone
调用另一个构造函数。它再次发生,又一次又一次......直到堆栈已满。
当它是静态的时,它只被调用一次,第一次使用这个类。
答案 1 :(得分:1)
第一个例子的问题是NodeOne类包含同一个类的实例。
当初始化类时,成员字段被初始化,这反过来导致它自己的字段被初始化,依此类推,在一个永无止境的循环中(实际上它在jvm达到最大堆栈大小时结束,因为每个构造函数都被调用使用了一点)。
一般认为在课堂上设置这样的字段是不好的做法,因为它可能导致这种类型或错误。请注意,可以在main中实例化该类。
答案 2 :(得分:0)
这里的问题是您正在进行递归通话。当您调用构造函数NodeOne()
时,它会尝试转到类NodeOne
并检查其属性。它在那里找到属性nodeone
,它需要使用构造函数进行实例化,该构造函数将为新实例分配新的内存地址。此实例还包含属性nodeone
,该属性也需要实例化。在这里它循环并循环,直到它消耗所有JVM内存。但是如果你使用static,它将只分配一个内存地址,其内容java将为每个实例化进行修改。