无法捕获的ChuckNorrisException

问题

是否有可能在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);因为如果你抛出这样的异常会发生这种情况;)