为什么在代码位于try和catch语句中时会抛出StackOverflowError?

huangapple go评论74阅读模式
英文:

Why is a StackOverflowError being thrown, when the code is in a try and catch statement?

问题

以下是翻译好的部分:

我正在尝试为我自己创建的一种语言编写一个解释器的API到目前为止我已经有了三个类

这是来自' CandleInterpreter '主API类的一部分代码

    protected Class<?> inputClass;
	protected Class<?> outputClass;
	public String input;
	protected String currentFile;
	
	public CandleInterpreter(Class<?> inputClass, Class<?> outputClass) {
		this.inputClass = inputClass;
		this.outputClass = outputClass;
		this.input = "";
		this.currentFile = "";
	}

这个类包含了这个方法

    public void output(String message) {
		try {
			outputClass.getConstructor(String.class).newInstance(message);
		} catch (Exception exception) {
			output("Output class is invalid.");
			System.exit(0);
		}
	}

这是来自' Output '类的一部分代码

    public class Output {
	    public Output(String message) {
		    System.out.println(message);
	    }
    }

这是来自' Main '类的一部分代码

    public static void main(String args[]) {
        CandleInterpreter interpreter = new CandleInterpreter(Input.class, Output.class);
        interpreter.output("Hello World!");
    }

这段代码运行良好但是在主类中当我将一个不同的类传递给'CandleInterpreter'对象而不是'Output.class'类时会抛出'StackOverflowError'错误

    Exception in thread "main" java.lang.StackOverflowError
	at java.base/java.lang.StringUTF16.compress(StringUTF16.java:158)
	at java.base/java.lang.String.<init>(String.java:3002)
	at java.base/java.lang.String.<init>(String.java:250)
	at java.base/java.util.StringJoiner.toString(StringJoiner.java:187)
	at java.base/java.lang.Class.methodToString(Class.java:3374)
	at java.base/java.lang.Class.getConstructor0(Class.java:3302)
	at java.base/java.lang.Class.getConstructor(Class.java:2110)
	at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:107)
	at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
    ...

我对为什么会抛出这个错误感到困惑因为我在try和catch语句中有代码行'outputClass.getConstructor(String.class).newInstance(message);'。有谁可以解释一下吗谢谢

-PrimeCubed
英文:

I am trying to write an API for an interpreter for a language of my own creation, and I have three classes so far:

Here is a snippet from class 'CandleInterpreter' (The main API class):

protected Class&lt;?&gt; inputClass;
protected Class&lt;?&gt; outputClass;
public String input;
protected String currentFile;
public CandleInterpreter(Class&lt;?&gt; inputClass, Class&lt;?&gt; outputClass) {
this.inputClass = inputClass;
this.outputClass = outputClass;
this.input = &quot;&quot;;
this.currentFile = &quot;&quot;;
}

this class contains this method:

public void output(String message) {
try {
outputClass.getConstructor(String.class).newInstance(message);
} catch (Exception exception) {
output(&quot;Output class is invalid.&quot;);
System.exit(0);
}
}

Here is a snippet from class 'Output':

public class Output {
public Output(String message) {
System.out.println(message);
}
}

And here is a snippet from class 'Main':

public static void main(String args[]) {
CandleInterpreter interpreter = new CandleInterpreter(Input.class, Output.class);
interpreter.output(&quot;Hello World!&quot;);
}

This code works fine, but in the main class, when I pass a different class into the 'CandleInterpreter' object, instead of the 'Output.class' class, a 'StackOverflowError' is thrown:

Exception in thread &quot;main&quot; java.lang.StackOverflowError
at java.base/java.lang.StringUTF16.compress(StringUTF16.java:158)
at java.base/java.lang.String.&lt;init&gt;(String.java:3002)
at java.base/java.lang.String.&lt;init&gt;(String.java:250)
at java.base/java.util.StringJoiner.toString(StringJoiner.java:187)
at java.base/java.lang.Class.methodToString(Class.java:3374)
at java.base/java.lang.Class.getConstructor0(Class.java:3302)
at java.base/java.lang.Class.getConstructor(Class.java:2110)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:107)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
at CandleAPI.CandleInterpreter.output(CandleInterpreter.java:109)
...

I am confused why this error is being thrown, as I have the line of code 'outputClass.getConstructor(String.class).newInstance(message);' in a try and catch statement. Can anyone explain? Thanks.

-PrimeCubed

答案1

得分: 2

A StackOverflowError is an Error, not an Exception. Catching Exception will not catch a StackOverflowError.

You can catch it - either as StackOverflowError, Error or Throwable - but what do think you can achieve by doing so? Errors are meant to be unrecoverable conditions.

英文:

A StackOverflowError is an Error, not an Exception. Catching Exception will not catch a StackOverflowError.

You can catch it - either as StackOverflowError, Error or Throwable - but what do think you can achieve by doing so? Errors are meant to be unrecoverable conditions.

答案2

得分: 2

我没有仔细阅读你的代码,但StackOverflowError是一个错误,而不是异常。

StackOverflowError继承自VirtualMachineError

VirtualMachineError继承自Error

Error继承自Throwable

因此,在这种情况下,你可以尝试捕获一个Throwable。

要查找根本原因,你应该查看调用栈,并找出如何可能导致堆栈溢出。

英文:

I don't read your code carefully, but StackOverflowError is an error not an exception.

StackOverflowError extends VirtualMachineError
VirtualMachineError extends Error
Error extends Throwable

Show in this case, you can try cat a Throwable instead.
For root cause, you should look at you call stack and figure it out how can it be stack overflow.

答案3

得分: 1

以下是翻译好的内容:

抛出异常的代码行如下:

output("Output class is invalid.");

因此,代码进入捕获块并尝试执行:

output("Output class is invalid.");

相反,如果您将捕获块中的代码替换为以下内容,则不会进入无限循环:

System.out.println("Output class is invalid.");
英文:

The following line is throwing the exception :

     output(&quot;Output class is invalid.&quot;);

Hence code goes into catch block and tries to execute :

       output(&quot;Output class is invalid.&quot;);

Instead if you replace your code in catch block to below, it will not get into infinite loop:

        System.out.println(&quot;Output class is invalid.);

huangapple
  • 本文由 发表于 2020年4月4日 22:15:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/61029428.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定