有没有办法让Runnable的run()抛出exception?

我在一个实现了Runnable的类的run()中调用的方法被devise为抛出一个exception。

但Java编译器不会让我这样做,并build议我用try / catch来包围它。

问题是通过围绕它try / catch我使特定的 运行()无用。 我想抛出这个exception。

如果我为run()本身指定了throws ,那么编译器会抱怨说Exception is not compatible with throws clause in Runnable.run()

不要让run()抛出exception,通常我完全没问题。 但我有独特的情况,我必须有这个function。

如何解决这个限制?

如果你想把一个实现了Runnable的类传递给Thread框架,那么你必须按照这个框架的规则来发挥,参见Ernest Friedman-Hill的回答,为什么这样做不是一个好主意。

我有一个预感,但是,你要直接在你的代码中调用run方法,所以你的调用代码可以处理exception。

这个问题的答案很简单。 不要使用Thread库中的Runnable接口,而是使用修改的签名来创build自己的接口,以允许检查exception被抛出,例如

 public interface MyRunnable { void myRun ( ) throws MyException; } 

您甚至可以创build一个适配器,将该接口转换为适合在Thread框架中使用的真正的Runnable (通过处理检查的exception)。

您可以使用Callable ,将其提交给ExecutorService并等待ExecutorService FutureTask.isDone()返回的FutureTask.isDone()结果。

isDone()返回true时,调用FutureTask.get() 。 现在,如果你的Callable引发了一个Exception那么FutureTask.get()将会抛出一个Exception并且你可以使用Exception.getCause()来访问原始exception。

如果run()抛出一个检查的exception,那么会发生什么呢? 你没有办法把run()调用放在一个处理程序中,因为你没有编写调用它的代码。

您可以在run()方法中捕获您检查的exception,并在其位置中引发一个未经检查的exception(即RuntimeException )。 这将使用堆栈跟踪来终止线程; 也许这就是你所追求的。

如果你想让你的run()方法在某处报告错误,那么你可以为run()方法的catch块提供一个callback方法来调用; 该方法可以将exception对象存储在某处,然后您感兴趣的线程可以在该位置find对象。

是的,有一种方法可以从run()方法抛出一个检查的exception,但这太糟糕了,我不会分享它。

以下是你可以做的事情; 它使用与运行时exception相同的机制:

 @Override public void run() { try { /* Do your thing. */ ... } catch (Exception ex) { Thread t = Thread.currentThread(); t.getUncaughtExceptionHandler().uncaughtException(t, ex); } } 

正如其他人所指出的,如果你的run()方法真的是一个Thread的目标,那么抛出一个exception是没有意义的,因为它是不可观测的。 抛出一个exception具有和不抛出exception(无)相同的效果。

如果它不是Thread目标,请不要使用Runnable 。 例如, Callable可能更适合。

你的要求没有任何意义。 如果你想通知被调用的线程发生了exception,你可以通过callback机制来完成。 这可以通过处理程序或广播或任何你能想到的。

我认为听者模式可能会帮助你解决这个问题。 如果run()方法发生exception,请使用try-catch块,并在catch中发送exception事件的通知。 然后处理你的通知事件。 我认为这将是一个更清洁的方法。 这个SO链接给你一个有用的指针,指向这个方向。

最简单的方法是定义自己的扩展RuntimeException类而不是Exception类的exception对象。