好的,所以我在SO和程序员之间有一堆与例外有关的问题,但是要问的是这么多,要么我不知道要输入什么,要么不知道有很多人有问。
所以,让我们说我有一个抛出FileNotFoundException
(FNFE)的方法。然后我有另一个方法使用第一个方法,但也抛出IOException
(IOE)。
我的处理程序会同时捕获它们并对每个执行不同的操作,但我的IDE(IntelliJ)发出信号,我发现了一个更普遍的异常,' java.io.IOException',在投掷中已列出"。
如果我这样做,我知道它有效:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
try {
// Method that generates the FNFE
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
catch (FileNotFoundException fnfe) {
throw fnfe;
}
if (!file.exists())
file.createNewFile(); // IOE
return file;
}
但是我需要明确地做吗?如果没有显式版本, 有时 工作没有,或者更危险,它是否有效。
为了确保我们在同一页面上,这就是我最初写的东西:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
if (!file.exists())
file.createNewFile();
return file;
}
但我不确定会发生什么,是FNFE被抛弃还是被吞没了?我的目的是分别抓住它们并为另一个做不同的事情。
答案 0 :(得分:6)
您只需在throws
列表中包含更常规的例外情况。这已经指定该方法可以抛出此异常的任何子类。
特别是,您必须处理更一般的异常,并且此异常处理程序也将处理子类。如果要显式处理子类,则必须在更常见的异常之前捕获它:
try {
...
}
catch (FileNotFoundException e) {
// handle subclass
}
catch (IOException e) {
// handle general exception (this will not be executed if the
// exception is actually a FileNotFoundException
}
答案 1 :(得分:1)
如果你已经有了IOException,那么从throws子句中省略FileNotFoundException是完全可以的。
这样做根本不会影响行为。 FileNotFoundException仍将被抛出,您可以显式地捕获它(以及还有一个不同的,更通用的IOException捕获)。
在throws子句中使用IOException只是声明将从此方法抛出 IOException或其任何子类。 FileNotFoundException包含在其中。
答案 2 :(得分:0)
但是我需要明确地做吗?如果没有,或者更危险的是,它有时可以在没有明确版本的情况下工作。
是。您必须明确地执行此操作,因为它是已检查的例外。
直接抛弃异常:
如果您只是将这些已检查的异常添加到方法签名中,这意味着如果在方法标题中添加throws子句,如throws IOException
,那么您无需捕获方法中的任何位置。
但这样做有一个缺陷,如果您在代码中逐行访问n个文件,并且每行都可能抛出IOException,如果引发异常。您必须关闭文件 .close()
,然后再将其退回到被调用的方法。因此,仅使用此throws子句将不允许您这样做。
因此,只需捕获异常并在catch or finally block中执行必要的操作。
只有当您不需要执行任何操作时,并且如果您希望将异常弹出到被调用方法并且被调用方法处理它,则只需将throws签名添加到方法中。
答案 3 :(得分:0)
以下是Java语言规范对say的要求:
如果V的运行时类型与(第5.2节)a分配兼容 try语句的任何catch子句的可捕获异常类, 然后选择第一个(最左边)这样的catch子句。值V 被分配给所选catch子句的参数,以及 执行该catch子句的块,然后有一个选择: ...
(强调和省略号)。
因此,如果您希望执行更具体的catch
子句,则必须将其放在捕获列表中。
答案 4 :(得分:-2)
如果没有,你可以先捕获子类异常,然后是像这样的常规异常类
try{
// something
} catch(FileNotFoundException fne){
// Handle the exception here
} catch(IOException ioe) {
// Handle the IOException here
}