此代码编译时没有错误:
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
。
答案 0 :(得分:4)
简短的回答:你可以这样做,因为IOException
是一个Exception
。
public V call() throws Exception
表示“此方法可以抛出Exception
而没有其他已检查的异常!”。
如果你现在覆盖这个方法:
public MessageSource call() throws IOException
你实际上是在说“我们会被允许抛出任何Exception
但我们自愿将自己限制为一个子集:IOException
及其子女”。
你甚至可以这样做:
public Something call()
根本没有throws
:“我们将被允许抛出任何Exception
,但我保证我们不会抛出任何已检查的异常!”
答案 1 :(得分:2)
当覆盖抛出一些异常的方法时,overriden方法必须抛出与覆盖方法或其某些超类相同的异常。
中对此进行了描述假设
B
是类或接口,A
是B
的超类或超接口,n
中的方法声明B
会覆盖或隐藏m
中的方法声明A
。然后:
- 如果
n
有throws
子句提及任何已检查的异常类型,则m
必须具有throws子句,否则会发生编译时错误。- 对于
n
的throws子句中列出的每个已检查异常类型,在throws
m
子句的删除中必须出现相同的异常类或其中一个超类型强>;否则,发生编译时错误。
(其中n
会覆盖m
)