当前位置: 首页 > 知识库问答 >
问题:

为什么这个Java代码会产生堆栈溢出错误?

樊飞飙
2023-03-14

下面的代码在执行时会产生堆栈溢出错误。然而,如果移除其中任何一个

  • static final GenerateStackOverflow E1=新GenerateStackOverflow(“值1”)
  • final GenerateStackOverflow E2=新GenerateStackOverflow(“值2”)

它运行时没有堆栈溢出错误。如果我有上面两行,但如果只有一行在类中,为什么我没有错误?

public class GenerateStackOverflow {

    private final String value; 

    static final GenerateStackOverflow E1 = new GenerateStackOverflow("value1");
    final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");


    public GenerateStackOverflow(String value) {
        System.out.println("GenerateStackOverflow.GenerateStackOverflow()");
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public static void main(String[] args) {
        GenerateStackOverflow.class.getName();
    }
}

共有3个答案

徐弘图
2023-03-14
匿名用户

静态最终行表示每次加载类时都要实例化一个GenerateStackOverflow;这只是一次。最终行表示每次实例化类时都要实例化一个。

您的main方法加载类,但不实例化它。因此:

  • 只有静态最终行,加载类实例化一个GenerateStackOverflow,就是这样
  • 对于最终的行,加载类不会进一步执行任何操作
  • 在这两种情况下,加载类实例化一个GenerateStackOverflow(由于静态行),然后实例化另一个GenerateStackOverflow(由于非静态行),然后实例化另一个GenerateStackOverflow,依此类推,直到获得堆栈溢出。

如果您的main方法是:

new GenerateStackOverflow("boom");

... 那么,只要非静态行就足以导致溢出。

贺栋
2023-03-14

构造函数调用自己:

final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");

所以,要构造一个实例,你需要构造一个实例,这需要构造一个实例,等等。

你的程序的主方法加载类。有一个静态字段调用类的构造函数,这会造成堆栈溢出。所以删除静态变量隐藏了问题,因为构造函数从未被调用过。删除非静态变量完全删除了递归调用,这修复了问题。

皇甫建木
2023-03-14

生成StackOverflow Error时都需要。当您包含这一行时:

static final GenerateStackOverflow E1 = new GenerateStackOverflow("value1");

当类首次被访问时,会创建GenerateStackOverflow的实例。

不包括这一行:

final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");

一切都很好。但这句话很关键。每次创建GenerateStackOverflow的实例时,它都会尝试初始化其成员变量E2——另一个GenerateStackOverflow对象。然后,该实例将其E2初始化为另一个GenerateStackOverflow对象。这会一直持续到出现堆栈溢出错误

如果包含第二行,但不包含第一行,则不会创建任何实例,也不会输入无限递归。

 类似资料:
  • 问题内容: 下面的代码在执行时会产生堆栈溢出错误。但是,如果删除其中一个 它运行时没有堆栈溢出错误。如果我有以上两行,而类中只有其中一行,则没有错误,怎么会出现堆栈溢出错误呢? 问题答案: 两者都需要生成一个。当包含此行时: 首次访问该类时,将创建的实例。 不包括此行: 一切都很好。但是这条线很关键。每次创建的实例时,它都会尝试初始化其成员变量-另一个对象。然后, 该 实例将 其 初始化为另一个对

  • 问题内容: 我的第一段代码是我的项目对象文件;第二个是主班。在运行代码没有任何问题之前,但是在添加读写文件之后,我的代码开始收到堆栈流错误。只是正在调用错误的代码段。 我的主班: 如何找到导致堆栈溢出的地方? 问题答案: 创建: 并创造 因此,在初始化时,您将不断创建这些对象 有一个类似的Baeldung示例,用于获取StackOverflowError 由于ClassOne的构造函数实例化了Cl

  • 问题内容: 下面给出的代码显示了运行时的Stackoverflow错误。但是,如果我使另一个类CarChange创建Car的对象,它将成功运行。我是一个初学者,请执行以下代码以了解在Java中进行向上转换的重要性。 问题答案: 一个stackoverflow通常意味着您有一个无限循环。 收到此消息的原因是因为您从testdrive方法调用驱动器,并且在该方法中再次调用drive。

  • 令我惊讶的是,即使在Java中发生了StackOverflowerError之后,仍然可以继续执行。 我知道StackOverflowerError是类错误的子类。类错误被描述为“Throwable的一个子类,表示合理的应用程序不应试图捕捉的严重问题。” 这听起来更像是一个建议而不是规则,补充说捕获像StackOverflow Error这样的错误实际上是允许的,这取决于程序员不这样做的合理性。看

  • 问题内容: 我到处都是,找不到可靠的答案。根据文档,在以下情况下,Java引发java.lang.StackOverflowError错误: 由于应用程序递归过深而在堆栈溢出时抛出。 但这提出了两个问题: 不仅通过递归,还有其他方法可以使堆栈溢出吗? 是在JVM实际溢出堆栈之前还是之后发生StackOverflowError? 详细阐述第二个问题: 当Java引发StackOverflowErro