抛出主要异常和子类型,是否有正确的方法?

时间:2015-09-28 12:59:51

标签: java exception-handling

好的,所以我在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被抛弃还是被吞没了?我的目的是分别抓住它们并为另一个做不同的事情。

5 个答案:

答案 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
   }