这个问题在这里已经有答案了:
为什么重写方法不能抛出比重写方法更宽的异常(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
例如。
2条答案
按热度按时间yizd12fk1#
简而言之:你可以这样做是因为
IOException
is-a公司Exception
.意思是“这个方法可以抛出一个
Exception
没有其他检查异常。如果您现在这样重写此方法:
你实际上是在说“我们可以
Exception
但我们自愿将自己限制在一个子集内:IOException
以及它的孩子们”。你甚至可以这样做:
没有
throws
“我们可以扔任何东西Exception
,但我保证我们不会抛出任何选中的异常!”3b6akqbq2#
当重写抛出某些异常的方法时,被重写的方法必须抛出与重写方法或其某些超类相同的异常。
这在jls#8.4.8.3中有描述:
假设
B
是类或接口,并且A
是的超类或超接口B
,以及方法声明n
在B
重写或隐藏方法声明m
在A
. 然后:如果
n
有一个throws
子句,然后m
必须有throws子句,否则会发生编译时错误。对于的throws子句中列出的每个选中的异常类型
n
,则必须在throws
条款m
; 否则,将发生编译时错误。(其中
n
覆盖m
)