0

此代码编译没有错误:

private FutureTask<MessageSource> loadingTask(final Locale locale)
{
    return new FutureTask<MessageSource>(new Callable<MessageSource>()
    {
        @Override
        public MessageSource call()
            throws IOException
        {
            return loader.load(locale);
        }
    });
}

但是Callable接口定义了这一点:

public V call()
    throws Exception;

我怎么可以声明我的覆盖抛出IOException

注意:我已经看到并利用了这一点,CacheLoader例如 Guava。

4

2 回答 2

4

简短的回答:你可以这样做,因为IOExceptionis-a Exception

public V call() throws Exception

意思是“这个方法可以抛出一个Exception并且没有其他检查的异常!”。

如果您现在像这样覆盖此方法:

public MessageSource call() throws IOException

您实际上是在说“我们可以扔任何Exception东西,但我们自愿将自己限制在一个子集:IOException及其子集”。

你甚至可以这样做:

public Something call()

根本没有throws:“我们将被允许抛出 any Exception,但我保证我们根本不会抛出任何已检查的异常!”

于 2013-06-06T09:20:18.420 回答
2

当重写抛出一些异常的方法时,被重写的方法必须抛出与重写方法或其某些超类相同的异常。

这在JLS #8.4.8.3中有描述:

假设它B是一个类或接口,并且A是 的超类或超接口,并且中B的方法声明覆盖或隐藏 中的方法声明。然后:nBmA

  • 如果n有一个throws子句提到任何已检查的异常类型,则m必须有一个 throws 子句,否则会发生编译时错误。
  • 对于在 throws 子句中列出的每个已检查异常类型n相同的异常类或其超类型之一必须出现在;throws子句m的 erasureof 中。否则,会发生编译时错误。

(其中n覆盖m

于 2013-06-06T09:20:00.303 回答