为什么runnable run()不能抛出已检查的异常?

Inq*_*ive 17 java java.util.concurrent

根据JCIP第6.3.2 :

Runnable是一个相当有限的抽象; run无法返回值或抛出已检查的异常.

run() 不能返回一个值,因为它的返回类型是void,但为什么不能抛出一个已检查的异常?

Pet*_*rey 23

它不能抛出一个已检查的异常,因为它没有被声明为从第一个版本抛出一个已检查的异常,而且更改它太危险了.

最初Runnable只用于包装Thread,并且假设开发人员想要捕获所有已检查的异常并处理它们而不是记录它们System.err.

Callable当您可以将单个任务添加到Executor可以捕获结果的位置Future以及抛出的任何异常时添加.

Callable 现在允许您返回一个值,并且可选地声明一个已检查的异常.

BTW:你可以说你不希望返回或从可调用中抛出一个已检查异常的一种方法是使用类似的东西

Callable<Void> callable = new Callable<Void>() {
    public Void call() {
        // do something
        return null;
    }
};
Run Code Online (Sandbox Code Playgroud)


Tom*_*son 5

run()不能抛出检查异常,因为它没有声明这样做。您不能在未声明的情况下抛出已检查的异常。

您也不能在覆盖或实现另一个不抛出该异常的方法的方法上声明受检查的异常。因此, 的实现Runnable不能简单地throws向其实现添加子句run()


Tom*_*son 5

这不是问题的答案.相反,它是Lukas Eder的答案的后续,显示了另一种将检查的异常走私到一个不被静态允许的地方的方法.这依赖于以下事实:如果使用newInstance任何已检查的异常调用无参数构造函数,它将向上抛出转义.

public class Thrower {

    private static final ThreadLocal<Exception> toThrow = new ThreadLocal<Exception>();

    public static void throwUnsafely(Exception e) {
        try {
            toThrow.set(e);
            Thrower.class.newInstance();
        } catch (InstantiationException f) {
            throw new RuntimeException("unexpected exception while throwing expected exception", f);
        } catch (IllegalAccessException f) {
            throw new RuntimeException("unexpected exception while throwing expected exception", f);
        } finally {
            toThrow.remove();
        }
    }

    private Thrower() throws Exception {
        throw toThrow.get();
    }

}
Run Code Online (Sandbox Code Playgroud)

这是一个真正古老的黑帽Java伏都教.不要这样做.除了聚会给人们留下深刻印象.