我知道下面的代码确实有意义:
try { ... }
catch (FileNotFoundException exc) { ... }
catch (IOException exc) { ... }
但是,在 throws子句中声明父级和子级异常是否有意义?
假设我有以下代码:
public void doSomething() throws FileNotFoundException, IOException { ... }
我们都知道FileNotFoundException
是IOException
的子类。现在以任何方式将 (可读性,性能等等)理解为这样,反对这一点:
public void doSomething() throws IOException { ... }
答案 0 :(得分:4)
对于Java编译器,子类是否在throws
子句中并不重要,因为超类异常将覆盖它。
但是,出于文档目的,它很重要。您的方法的调用者可能想知道它可以抛出子类异常,例如FileNotFoundException
,并以不同方式处理。
try {
doSomething();
}
catch (FileNotFoundException e) {
System.out.println("File not found!");
}
catch (IOException e) {
System.out.println("An I/O error has occurred: " + e.getMessage());
}
答案 1 :(得分:1)
有时候捕获两个异常是有意义的,只要首先指定子类异常(否则,我认为它甚至不会编译)。它允许您以不同于一般例外的方式处理您关心的特定异常。
例如,我有从套接字读取的代码。这是一个阻塞读取,我设置了超时,因为可能没有什么可读的。这就是为什么我抓住SocketTimeoutException
并且不做任何事情。另一方面,如果我得到其他IOException
s(IOException
是SocketTimeoutException
的间接超类),我会抛出异常,因为在尝试时发生了真正的失败从插座中读取。
catch (SocketTimeoutException ignEx) {
// -- ignore exception, as we are expecting timeout exceptions because
// -- there might be nothing to read
}
catch (IOException ioEx) {
throw new SomeException (...);
}
至于在方法签名中声明两者,没有必要在throws
子句中声明这两者,但是如果你在JavaDoc注释中记录了两个异常,它对你的方法的用户会很有用,并且描述抛出每一个的条件。