当前位置: 首页 > 知识库问答 >
问题:

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

滑骞尧
2023-03-14

根据JCIP第6.3.2节:

Runnable是一个相当有限的抽象;run无法返回值或引发选中的异常。

run()无法返回值,因为其返回类型为void,但为什么不能引发选中的异常?

共有3个答案

洪浩
2023-03-14

这不是问题的答案。相反,这是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();
    }

}

这是真正古老的甲级黑帽爪哇巫毒。永远不要这样做。除了在派对上给人留下深刻印象。

彭鹭洋
2023-03-14

run()无法引发选中的异常,因为它未声明要这样做。您不能在不声明的情况下抛出已检查的异常。

您也不能在重写或实现另一个不引发该异常的方法的方法上声明已检查的异常。因此,Runnable的实现不能简单地向run()的实现中添加抛出子句。

韦高格
2023-03-14

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

最初,Runnable(可运行)仅用于包装的线程中,并且假定开发人员希望捕获所有已检查的异常并处理它们,而不是将它们记录到系统中。错误。

当您可以将单个任务添加到执行器时,添加了可调用的执行器,您可以在执行器中捕获未来的结果以及引发的任何异常。

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

顺便说一句:你可以说你不想从一个可调用的对象中返回或抛出一个选中的异常,一种方法是使用

Callable<Void> callable = new Callable<Void>() {
    public Void call() {
        // do something
        return null;
    }
};
 类似资料:
  • 问题内容: 我在实现Runnable的类中的run()中调用的方法被设计为引发异常。 但是Java编译器不允许我这样做,建议我用try / catch包围它。 问题是,通过用try / catch包围它,我使 特定的 run()无效了。我 确实 想抛出该异常。 如果我指定的run()的本身,编译器会抱怨说。 通常,我对run()不会抛出异常完全满意 。但是,在我必须具有该功能的特殊情况下。 如何解

  • 编译器知道检查的异常不能在安全方法内抛出-所以也许它应该允许只捕获未检查的异常? 回到主要问题--有没有理由以这种方式实现捕获检查异常?这仅仅是设计中的一个缺陷还是我遗漏了一些重要的因素--也许是向后的不兼容性?在此场景中,如果只允许捕获,可能会出现什么问题?实例非常感谢。

  • 下面是我的代码。当我运行它时,我在线程“main”java.lang.IndexOutOfBoundsException:Index:3、Size:2中得到异常,而不是我的异常消息。谁能解释一下我做错了什么,为什么会这样?谢谢!

  • 问题内容: 我有一段代码以JSON字符串编码某种业务数据: 事情是: JSONException是一个检查的异常,但是 我真的不知道如何在编译时处理它。如果确实发生JSONException,则可能是代码中的错误,应该由 已经存在 的常规“全局未捕获异常处理程序” (例如this)来处理,并且已经执行了所有必要的日志记录和清理工作。 因此,我最终在调用方法中这样做: 这似乎是不幸中之大幸不是添加到

  • 考虑下面的java代码片段: 这在Eclipse(Neon.2,JDK 8)中实现,Sonarint执行静态代码分析。它提供了重构的建议: 重构此方法以引发最多一个已检查异常,而不是:java。lang.InstanceionException,java。lang.IllegalAccessException 这项建议的基础是什么最佳做法?我知道一般来说对检查异常有一些争议,但是为什么在这种情况下

  • 问题内容: 直接的答案是因为s接口被指定为不会引发异常。但是为什么呢? 或换句话说:我必须依赖可以引发异常的函数。从理论上讲,这不应该发生。但是,如果发生这种情况,我希望它脱离我正在使用的整个函数(在中)。即我希望它的行为就像发生未处理的异常一样。 似乎这不可能以一种显而易见的自然方式进行(因为如果接口说它不能抛出异常,就不会)。 我该如何解决?用丑陋的try / catch并打印出异常,并希望我