是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?

我想到的是使用拦截器或面向方面的编程。


当前回答

在finalize中调用System.exit(1),并抛出来自所有其他方法的异常副本,以便程序退出。

其他回答

在当前线程上模拟一个未捕获的异常是很容易的。这将触发未捕获异常的常规行为,从而在语义上完成工作。然而,它并不一定会停止当前线程的执行,因为实际上并没有抛出异常。

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的框架中调用。

这个主题的另一个变体是,您可以从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。所以不,无论你创建什么异常都会是Throwable的子类并且会被捕获。

你可以把ChuckNorris隐藏起来,也可以把他封装起来,也可以把他吞下去……

try {doChuckAction();} catch(ChuckNorrisException cne){/*做其他事情*/}

public class ChuckNorrisException extends Exception {
    public ChuckNorrisException() {
        System.exit(1);
    }
}

(当然,从技术上讲,这个异常永远不会被真正抛出,但是一个正确的ChuckNorrisException不能被抛出——它会先抛出你。)