callable:为什么我们可以“更改”实现上的异常?

uxh89sit  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(403)

这个问题在这里已经有答案了

为什么重写方法不能抛出比重写方法更宽的异常(15个答案)
7年前关门了。
此代码编译时没有错误:

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 ?
注:我已经看到,并利用这一点,与Guava的 CacheLoader 例如。

yizd12fk

yizd12fk1#

简而言之:你可以这样做是因为 IOException is-a公司 Exception .

public V call() throws Exception

意思是“这个方法可以抛出一个 Exception 没有其他检查异常。
如果您现在这样重写此方法:

public MessageSource call() throws IOException

你实际上是在说“我们可以 Exception 但我们自愿将自己限制在一个子集内: IOException 以及它的孩子们”。
你甚至可以这样做:

public Something call()

没有 throws “我们可以扔任何东西 Exception ,但我保证我们不会抛出任何选中的异常!”

3b6akqbq

3b6akqbq2#

当重写抛出某些异常的方法时,被重写的方法必须抛出与重写方法或其某些超类相同的异常。
这在jls#8.4.8.3中有描述:
假设 B 是类或接口,并且 A 是的超类或超接口 B ,以及方法声明 nB 重写或隐藏方法声明 mA . 然后:
如果 n 有一个 throws 子句,然后 m 必须有throws子句,否则会发生编译时错误。
对于的throws子句中列出的每个选中的异常类型 n ,则必须在 throws 条款 m ; 否则,将发生编译时错误。
(其中 n 覆盖 m )

相关问题