问题
是否有可能在Java中构造一段代码,这会使假设的“java.lang.ChuckNorrisException”无法捕获?
想到的想法是使用例如拦截器或aspect-oriented programming。
#1 热门回答(305 赞)
我没有试过这个,所以我不知道JVM是否会限制这样的东西,但也许你可以编译抛出ChuckNorrisException
的代码,但是在运行时提供了ChuckNorrisException
的类定义,它不会扩展Throwable。
更新:
它不起作用。它会生成验证错误:
Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow. Program will exit.
更新2:
实际上,如果禁用字节码验证器,你可以使用它! (-Xverify:none
)
更新3:
对于那些在家的人,这里是完整的脚本:
创建以下类:
public class ChuckNorrisException
extends RuntimeException // <- Comment out this line on second compilation
{
public ChuckNorrisException() { }
}
public class TestVillain {
public static void main(String[] args) {
try {
throw new ChuckNorrisException();
}
catch(Throwable t) {
System.out.println("Gotcha!");
}
finally {
System.out.println("The end.");
}
}
}
编译类:
javac -cp . TestVillain.java ChuckNorrisException.java
跑:
java -cp . TestVillain
Gotcha!
The end.
注释掉“extends RuntimeException”并仅重新编译ChuckNorrisException.java
:
javac -cp . ChuckNorrisException.java
跑:
java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain. Program will exit.
运行时无需验证:
java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"
#2 热门回答(113 赞)
在考虑了这个之后,我成功地创建了一个无法捕获的异常。然而,我选择将它命名为“JulesWinnfield”,而不是Chuck,因为它是一个蘑菇云铺设的母亲例外。此外,它可能不是你想到的,但它肯定不会被抓住。注意:
public static class JulesWinnfield extends Exception
{
JulesWinnfield()
{
System.err.println("Say 'What' again! I dare you! I double dare you!");
System.exit(25-17); // And you shall know I am the LORD
}
}
public static void main(String[] args)
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
System.out.println("There's a word for that Jules - a bum");
}
}
瞧瞧!未捕获的异常。
输出:
跑:再说'什么'!我赌你!我量你不敢! Java结果:8 BUILD SUCCESSFUL(总时间:0秒)
当我有更多的时间,我会看到我是否也想不出别的东西。
另外,看看这个:
public static class JulesWinnfield extends Exception
{
JulesWinnfield() throws JulesWinnfield, VincentVega
{
throw new VincentVega();
}
}
public static class VincentVega extends Exception
{
VincentVega() throws JulesWinnfield, VincentVega
{
throw new JulesWinnfield();
}
}
public static void main(String[] args) throws VincentVega
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
}
catch(VincentVega vv)
{
}
}
导致堆栈溢出 - 再次,异常仍未被捕获。
#3 热门回答(84 赞)
有了这样的例外,显然必须使用构造函数中的System.exit(Integer.MIN_VALUE);
因为如果你抛出这样的异常会发生这种情况;)