抛出异常与Java字节码

3

一个方法的 throws 列表在编译时显然起着作用。但是在运行时它是否有任何影响呢?

例如,如果我有一个没有 throws 列表的方法,并使用黑魔法字节码召唤并抛出一个 IncrediblyCheckedException,它会毫不犹豫地抛出吗?还是运行时验证器会注意到这一点,而抛出错误或其他东西呢?

1个回答

7
它对运行时没有任何影响。例如:
Thread.currentThread.stop(new Exception());

代码可以在任何地方编写,而该行代码将会抛出异常。

上述代码将从本地代码中抛出异常,但这里有另一个使用普通Java throw 的技巧:

public static void main(String[] args) {
    CurrentClass.<RuntimeException>sneakyThrow(new Exception());
}
@SuppressWarnings("unchecked")
private static <E extends Throwable> void sneakyThrow(Throwable t) throws E { 
  throw (E)t; 
}

1
实际上,我在生产应用程序中看到过类似 sneakyThrow 的东西。当几乎所有代码都专门围绕某种语言特性工作时,你就知道这个特性很糟糕。 - Antimony
我想到的那个叫做throwAsUnchecked。 - Antimony
我不是真的那么字面意思 :-) - Marko Topolnik
在Java 8中,Thread.currentThread().stop(new Exception());不再起作用。我认为在生产代码中使用“sneaky throw”的主要原因是在Java 7之前无法轻松地重新抛出Throwable。此外,在InvocationTargetException等上下文中使用它可能是有意义的,当您知道反射调用的方法仅引发正确的异常时。但这是相当特殊的情况,所以我不会指责Java语言。 - Holger
1
@holger 没错,这符合我的观察:首先,普通的Java开发人员不会想使用或看到使用 sneaky throw。那些最终使用它的人是对受检异常持“叛逆”态度的人。 - Marko Topolnik
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接