由Sun的javac制作的奇怪异常表条目 [英] Strange exception table entry produced by Sun's javac

查看:86
本文介绍了由Sun的javac制作的奇怪异常表条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于此计划:

class Test {
    public static void main(String[] args) {
        try {
            throw new NullPointerException();
        } catch (NullPointerException npe) {
            System.out.println("In catch");
        } finally {
            System.out.println("In finally");
        }
    }
}

Sun的 javac (v 1.6.0_24)生成以下字节码:

Sun's javac (v 1.6.0_24) produces the following bytecode:

public static void main(java.lang.String[]);

        // Instantiate / throw NPE
   0:   new     #2;         // class NullPointerException
   3:   dup
   4:   invokespecial   #3; // Method NullPointerException."<init>":()V
   7:   athrow

        // Start of catch clause
   8:   astore_1
   9:   getstatic       #4; // Field System.out
   12:  ldc     #5;         // "In catch"
   14:  invokevirtual   #6; // Method PrintStream.println
   17:  getstatic       #4; // Field System.out

        // Inlined finally block
   20:  ldc     #7;         // String In finally
   22:  invokevirtual   #6; // Method PrintStream.println
   25:  goto    39

        // Finally block
        // store "incomming" exception(?)
   28:  astore_2
   29:  getstatic       #4; // Field System.out
   32:  ldc     #7;         // "In finally"
   34:  invokevirtual   #6; // Method PrintStream.println

        // rethrow "incomming" exception
   37:  aload_2
   38:  athrow

   39:  return

使用以下异常表:

  Exception table:
   from   to  target type
     0     8     8   Class NullPointerException
     0    17    28   any
    28    29    28   any



我的问题是:为什么它包含异常表中的最后一个条目?!



据我所知,它基本上是如果 astore_2 抛出一个异常,捕获它,并重试相同的指令


My question is: Why on earth does it include that last entry in the exception table?!

As I understand it, it basically says "if the astore_2 throws an exception, catch it, and retry the same instruction".

即使使用空的try / catch / finally子句,例如

Such entry is produced even with empty try / catch / finally clauses such as

try {} catch (NullPointerException npe) {} finally {}






一些观察结果


  • Eclipse编译器不会产生任何此类异常表条目

  • JVM规范没有记录 astore 指令

  • 我知道JVM为任何指令抛出 VirtualMachineError 是合法的。我猜这个特殊的条目可以防止任何这样的错误从该指令传播出来。

  • Eclipse compiler does not produce any such exception table entry
  • The JVM spec does not document any runtime exceptions for the astore instruction.
  • I know that it is legal for the JVM to throw VirtualMachineError for any instruction. I guess the peculiar entry prevents any such errors from propagating out from that instruction.

推荐答案

那里只有两种可能的解释:编译器包含一个错误或者由于不明原因而放置一种水印。

There are only two possible explanations: the compiler contains a bug or it's placing a kind of watermark for obscure reasons.

该条目肯定是假的,因为finally块抛出的任何异常本身必须将执行流程发送到外部异常处理程序或最后阻止,但永远不要再次运行相同的finally块。

That entry is certainly bogus because any exception thrown by a finally block itself must send execution flow to outer exception handler or finally block, but never "run again" the same finally block.

此外,一个很好的证据表明它是一个bug / watermark事实上Eclipse(以及其他Java编译器)没有生成这样的条目,即使Eclipse生成的类在Sun的JVM上运行良好。

Also, a good evidence that it's a bug/watermark, is the fact that Eclipse (and perhaps other Java compilers) are not generating such entry, and even so Eclipse-generated classes work fine on Sun's JVM.

这就是说,这篇文章很有趣,因为它似乎是有效的并且验证了类文件。如果我是JVM实现者,我会忽略该条目并填写Sun / Oracle的错误!

That said, this post is interesting because it seems that the class file is valid and verified. If I were a JVM implementor, I would ignore that entry and fill a bug for Sun/Oracle!

这篇关于由Sun的javac制作的奇怪异常表条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆