构造函数中出现异常时,java编译器出错

问题描述 投票:0回答:2

也许有java内部的专家。 我在理解以下 java 代码的编译代码时遇到问题

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

我的问题: 第 7 行,堆栈内容为

  1. 参考 StringBuilder 实例
  2. 参考 StringBuilder 实例

调用 StringBuilder(String) 后,最后两个参数将被删除,因此堆栈仅包含

  1. 参考 StringBuilder 实例

这对于正常执行来说是可以的,但是当出现异常(地址14)时,堆栈将如下所示

  1. 参考 StringBuilder 实例
  2. 参考异常实例

将异常引用存储在本地变量 2 中之后,因此在 catch 结束时,堆栈上仍然保留了对字符串构建器的引用。

有人可以指出我哪里出错了吗?

谢谢, 冈特

java exception constructor
2个回答
0
投票

此行为是预期的。你调用了

new StringBuilder(null)
,那么即使抛出了异常,也会有一个
StringBuilder
的实例。

当然,这个对象永远不会(也不能)被操作,因为它没有引用:

sb
null
。垃圾收集器随时都会收集这个未使用的对象,但 JVM 拥有控制权,你无法预测它的行为。


0
投票

在这两种情况下,您都应该将 StringBuilder 类放在堆栈顶部(不是它的实例,只是类)。 确保您在“返回”逻辑中将其弹出,而不是在其他地方。

你可以发布一些代码吗?

© www.soinside.com 2019 - 2024. All rights reserved.