当构造函数中出现异常时,java编译器出错
也许有一位java内部构件专家。 我在理解以下java代码的编译代码时遇到问题当构造函数中出现异常时,java编译器出错,java,exception,compiler-construction,constructor,Java,Exception,Compiler Construction,Constructor,也许有一位java内部构件专家。 我在理解以下java代码的编译代码时遇到问题 public class TestException { public static void main(String[] args) { StringBuilder sb = null; try { sb = new StringBuilder(null); } catch (NullPointe
public class TestException
{
public static void main(String[] args)
{
StringBuilder sb = null;
try
{
sb = new StringBuilder(null);
}
catch (NullPointerException t)
{
}
if (sb != null)
{
System.out.print(sb.toString());
}
}
}
这将被编译为:
stack=3, locals=3, args_size=1
0: aconst_null
1: astore_1
2: new #2 // class java/lang/StringBuilder
5: dup
6: aconst_null
7: invokespecial #3 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
10: astore_1
11: goto 15
14: astore_2
15: aload_1
16: ifnull 29
19: getstatic #5 // Field java/lang/System.out:Ljava/io/OutStream;
22: aload_1
23: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
26: invokevirtual #7 // Method java/io/OutStream.print:(Ljava/lang/String;)V
29: return
Exception table:
from to target type
2 11 14 Class java/lang/NullPointerException
stack=3,locals=3,args\u size=1
0:aconst_null
1:astore_1
2:new#2//类java/lang/StringBuilder
5:dup
6:aconst_null
7:invokespecial#3//方法java/lang/StringBuilder。”“:(Ljava/lang/String;)V
10:astore_1
11:goto 15
14:astore_2
15:aload_1
16:ifnull 29
19:getstatic#5//fieldjava/lang/System.out:Ljava/io/OutStream;
22:aload_1
23:invokevirtual#6//方法java/lang/StringBuilder.toString:()Ljava/lang/String;
26:invokevirtual#7//方法java/io/OutStream.print:(Ljava/lang/String;)V
29:返回
例外情况表:
从到目标类型
2 11 14类java/lang/NullPointerException
我的问题是:
在第7行,堆栈内容为
冈特这种行为是意料之中的。您调用了
new StringBuilder(null)
,则存在StringBuilder
的实例,即使引发了异常
当然,这个对象永远不会(也不能)被操纵,因为它没有引用:
sb
isnull
。垃圾收集器将随时收集此未使用的对象,但JVM拥有控制权,您无法预测其行为。在这两种情况下,您都应该将StringBuilder类放在堆栈顶部(不是它的实例,只是类)。确保在“返回”逻辑中弹出它,而不是在其他地方
您可以发布一些代码吗?您是否打算不在堆栈上使用字符串生成器?它仍然在范围内,所以它应该在那里。请参阅我对下面答案的评论。。。枪械问题不是“死”的问题。我试图编写一个jvm,由于这种行为,我遇到了堆栈超出估计范围的问题。(我已经编写了一个小型测试程序,其中我不止一次遇到过这种情况)。“真正的”java似乎没有受到干扰,如果我把代码放在一个无止境的循环中,它永远不会产生错误……我认为您必须在JVM中处理这种类型的问题。这是你写的任务。我想象不出你对这条线还有什么期待。是的。只有对实例的引用。在本例中(尽可能多),我认为它是对类实例的引用,而不是对StringBuilder实例的引用。这两种方式都不重要,你需要确保你一直都在从堆栈中弹出它们,不管是否有异常。你好,Ted,澄清一下:堆栈上只有引用(引用实例…)。发布一些(虚拟机的)代码似乎不是很有帮助,因为这必须占虚拟机代码总数的80%。我的问题是,当我对生成的java代码的解释没有失败时,在处理异常以“消除”不必要的引用时会出现一种特殊情况。否则,堆栈可能会增长到估计大小以上。