是否有可能在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"
其他回答
在当前线程上模拟一个未捕获的异常是很容易的。这将触发未捕获异常的常规行为,从而在语义上完成工作。然而,它并不一定会停止当前线程的执行,因为实际上并没有抛出异常。
Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.
这实际上在(非常罕见的)情况下很有用,例如当需要适当的错误处理时,但该方法从捕获(并丢弃)任何Throwable的框架中调用。
任何代码都可以捕获Throwable。所以不,无论你创建什么异常都会是Throwable的子类并且会被捕获。
抛出的任何异常都必须扩展Throwable,因此总是可以捕获它。所以答案是否定的。
如果你想让它难以处理,你可以重写方法getCause(), getMessage(), getStackTrace(), toString()抛出另一个java.lang.ChuckNorrisException。
在构造函数中,可以启动一个反复调用originalThread的线程。停止(ChuckNorisException.this)
线程可以重复捕获异常,但会一直抛出异常,直到异常死亡。
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
System.exit(1);
}
}
(当然,从技术上讲,这个异常永远不会被真正抛出,但是一个正确的ChuckNorrisException不能被抛出——它会先抛出你。)