是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?
我想到的是使用拦截器或面向方面的编程。
是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?
我想到的是使用拦截器或面向方面的编程。
当前回答
Two fundamental problems with exception handling in Java are that it uses the type of an exception to indicate whether action should be taken based upon it, and that anything which takes action based upon an exception (i.e. "catch"es it) is presumed to resolve the underlying condition. It would be useful to have a means by which an exception object could decide which handlers should execute, and whether the handlers that have executed so far have cleaned things up enough for the present method to satisfy its exit conditions. While this could be used to make "uncatchable" exceptions, two bigger uses would be to (1) make exceptions which will only be considered handled when they're caught by code that actually knows how to deal with them, and (2) allow for sensible handling of exceptions which occur in a finally block (if a FooException during a finally block during the unwinding of a BarException, both exceptions should propagate up the call stack; both should be catchable, but unwinding should continue until both have been caught). Unfortunately, I don't think there would be any way to make existing exception-handling code work that way without breaking things.
其他回答
实际上,公认的答案并不是那么好,因为Java需要在没有验证的情况下运行,即代码在正常情况下无法工作。
AspectJ拯救了真正的解决方案!
异常类:
package de.scrum_master.app;
public class ChuckNorrisException extends RuntimeException {
public ChuckNorrisException(String message) {
super(message);
}
}
方面:
package de.scrum_master.aspect;
import de.scrum_master.app.ChuckNorrisException;
public aspect ChuckNorrisAspect {
before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
throw chuck;
}
}
示例应用程序:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
catchAllMethod();
}
private static void catchAllMethod() {
try {
exceptionThrowingMethod();
}
catch (Throwable t) {
System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
}
}
private static void exceptionThrowingMethod() {
throw new ChuckNorrisException("Catch me if you can!");
}
}
输出:
Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
at de.scrum_master.app.Application.main(Application.java:5)
这个主题的另一个变体是,您可以从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是一个受控异常,则捕获没有抛出的异常。
抛出的任何异常都必须扩展Throwable,因此总是可以捕获它。所以答案是否定的。
如果你想让它难以处理,你可以重写方法getCause(), getMessage(), getStackTrace(), toString()抛出另一个java.lang.ChuckNorrisException。
在finalize中调用System.exit(1),并抛出来自所有其他方法的异常副本,以便程序退出。
任何代码都可以捕获Throwable。所以不,无论你创建什么异常都会是Throwable的子类并且会被捕获。