是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?
我想到的是使用拦截器或面向方面的编程。
是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?
我想到的是使用拦截器或面向方面的编程。
当前回答
我没有尝试过这个,所以我不知道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:没有)
更新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
Run:
java -cp . TestVillain
Gotcha!
The end.
注释掉"extends RuntimeException",只重新编译ChuckNorrisException.java:
javac -cp . ChuckNorrisException.java
Run:
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"
其他回答
经过思考,我成功地创建了一个不可捕捉的异常。然而,我选择取名为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)
{
}
}
导致堆栈溢出-同样,异常仍然未捕获。
不。Java中的所有异常都必须成为Java .lang的子类。虽然这可能不是一个好的实践,但你可以像这样捕获每种类型的异常:
try {
//Stuff
} catch ( Throwable T ){
//Doesn't matter what it was, I caught it.
}
有关更多信息,请参阅java.lang.Throwable文档。
如果您试图避免检查异常(必须显式处理的异常),那么您将希望继承Error或RuntimeException类。
Java中唯一的chucknorrisexception应该是OutOfMemoryError和StackOverflowError。
实际上,您可以“捕获”它们,这意味着在抛出异常时将执行catch(OutOfMemoryError ex),但该块将自动将异常重新抛出给调用者。
我不认为公共类ChuckNorrisError extends Error可以解决这个问题,但是你可以尝试一下。我没有找到关于扩展错误的文档
你可以把ChuckNorris隐藏起来,也可以把他封装起来,也可以把他吞下去……
try {doChuckAction();} catch(ChuckNorrisException cne){/*做其他事情*/}
这个主题的另一个变体是,您可以从Java代码抛出未声明的受控异常。由于它没有在方法签名中声明,所以编译器不会让您捕获异常本身,尽管您可以将其作为java.lang.Exception捕获。
这里有一个帮助类,它允许你抛出任何东西,无论是否声明:
public class SneakyThrow {
public static RuntimeException sneak(Throwable t) {
throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
}
private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
throw (T) t;
}
}
现在扔SneakyThrow。溜(新ChuckNorrisException ());抛出ChuckNorrisException,但编译器抱怨
try {
throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}
如果ChuckNorrisException是一个受控异常,则捕获没有抛出的异常。