这种处理Java中IO异常的模式正确吗?

这种处理Java中IO异常的模式正确吗?,java,io,Java,Io,在下面的代码段中,如果抛出ex1,它将被第二个catch块捕获,还是会被抛出回方法的调用方 如果它被抛出回调用方,然后在finally块(ex2)中发生第二个异常,这是否意味着将有两个异常被抛出回调用方(ex1和ex2) 这两个异常都将被抛出回调用方。。。尽管在任何特定情况下都有一个例外。如果外部try块的主体抛出,然后close也抛出,则调用者只会看到第二个异常 然而,有一个catch块只是为了重新调用是没有意义的。您的代码将更清晰,如下所示: try { // write to file

在下面的代码段中,如果抛出ex1,它将被第二个catch块捕获,还是会被抛出回方法的调用方

如果它被抛出回调用方,然后在finally块(ex2)中发生第二个异常,这是否意味着将有两个异常被抛出回调用方(ex1和ex2)


这两个异常都将被抛出回调用方。。。尽管在任何特定情况下都有一个例外。如果外部try块的主体抛出,然后
close
也抛出,则调用者只会看到第二个异常

然而,有一个
catch
块只是为了重新调用是没有意义的。您的代码将更清晰,如下所示:

try {
  // write to file
} finally {
  aBufferedWriter.close();
}
在Java 7中,a可以自动执行以下操作:

try (BufferedWriter writer = new BufferedWriter(...)) {
    // Use the writer here
} // The writer is auto-closed here

通过这种方式,您还可以在关闭时获取异常,而不是在主体中获取异常。使用。

这两个异常都将被抛出回调用方。。。尽管在任何特定情况下都有一个例外。如果外部try块的主体抛出,然后
close
也抛出,则调用者只会看到第二个异常

然而,有一个
catch
块只是为了重新调用是没有意义的。您的代码将更清晰,如下所示:

try {
  // write to file
} finally {
  aBufferedWriter.close();
}
在Java 7中,a可以自动执行以下操作:

try (BufferedWriter writer = new BufferedWriter(...)) {
    // Use the writer here
} // The writer is auto-closed here

通过这种方式,您还可以在关闭时获得异常,与主体中的异常分开使用。

取决于设计。你也可以试试

try{
    try{
      //write to file
    }finally{
       aBufferedWriter.close();
    }
}catch(IOException e){
}

如果要抛出异常,为什么还要捕获它呢。

取决于设计。你也可以试试

try{
    try{
      //write to file
    }finally{
       aBufferedWriter.close();
    }
}catch(IOException e){
}
如果要抛出异常,为什么还要捕获它呢

在下面的代码段中,如果抛出ex1,它将被第二个catch块捕获,还是会被抛出回方法的调用方

不,它不会被
finally
中的
catch
块捕获,前提是finally块中没有异常,因此异常
ex1
将被抛出回调用方方法


如果它被抛出回调用方,然后在finally块(ex2)中发生第二个异常,这是否意味着将有两个异常被抛出回调用方(ex1和ex2)

在这种情况下,由于在finally块中抛出异常,它将覆盖在外部catch块中抛出的异常,并导致异常
ex2
被抛出回调用方方法

只有其中一个异常会被抛出回调用方方法,以执行一次,而不是两个。这就是说,拥有一个
catch
块只是为了抛出已捕获的异常,实际上是毫无意义的

在下面的代码段中,如果抛出ex1,它将被第二个catch块捕获,还是会被抛出回方法的调用方

不,它不会被
finally
中的
catch
块捕获,前提是finally块中没有异常,因此异常
ex1
将被抛出回调用方方法


如果它被抛出回调用方,然后在finally块(ex2)中发生第二个异常,这是否意味着将有两个异常被抛出回调用方(ex1和ex2)

在这种情况下,由于在finally块中抛出异常,它将覆盖在外部catch块中抛出的异常,并导致异常
ex2
被抛出回调用方方法


只有其中一个异常会被抛出回调用方方法,以执行一次,而不是两个。这就是说,有一个
catch
块只是为了抛出已捕获的异常,这是毫无意义的

public void writeToFile(String file) throws IOException {
    IOException exception = null;
    OutputStream out = new FileOutputStream(file);
    try {
        // TODO: write data to file
    } catch (IOException ex) {
        // store exception for later rethrow
        exception = ex;
    } finally {
        try {
            out.close();
        } catch (IOException ex) {
            // do NOT supress 'outer' exception:
            if (exception == null) {
                exception = ex;
            }
        }
    }

    if (exception != null) {
        throw exception;
    }
}
看起来很疯狂,但这涵盖了所有可能性并绕过了异常抑制异常(当在
finally
语句中抛出异常时,它会抑制
try
块中发生的“真实”异常(如果有)

但是,为了可读性起见,您可能可以忍受被抑制的异常,并这样做:

OutputStream out = new FileOutputStream(file);
try {
    // TODO: write data to file
} finally {
    out.close(); // if an exception is thrown here, it hides the original exception
}
另见

自Java 7以来,您可以(几乎)通过try with resource语句执行相同的操作:

public void writeToFile(String file) throws IOException {
    try (OutputStream out = new FileOutputStream(file)) {
    // TODO: write data to file
    }
}
请注意,关闭资源时引发的异常不会抑制原始异常。相反,这些附加异常将作为“抑制异常”添加到基本异常中。您可以使用
baseException.getsupprested()
(Java7及更高版本!)获取它们


另请参见Java 7之前的

,真正准确的模式是

public void writeToFile(String file) throws IOException {
    IOException exception = null;
    OutputStream out = new FileOutputStream(file);
    try {
        // TODO: write data to file
    } catch (IOException ex) {
        // store exception for later rethrow
        exception = ex;
    } finally {
        try {
            out.close();
        } catch (IOException ex) {
            // do NOT supress 'outer' exception:
            if (exception == null) {
                exception = ex;
            }
        }
    }

    if (exception != null) {
        throw exception;
    }
}
看起来很疯狂,但这涵盖了所有可能性并绕过了异常抑制异常(当在
finally
语句中抛出异常时,它会抑制
try
块中发生的“真实”异常(如果有)

但是,为了可读性起见,您可能可以忍受被抑制的异常,并这样做:

OutputStream out = new FileOutputStream(file);
try {
    // TODO: write data to file
} finally {
    out.close(); // if an exception is thrown here, it hides the original exception
}
另见

自Java 7以来,您可以(几乎)通过try with resource语句执行相同的操作:

public void writeToFile(String file) throws IOException {
    try (OutputStream out = new FileOutputStream(file)) {
    // TODO: write data to file
    }
}
请注意,关闭资源时引发的异常不会抑制原始异常。相反,这些附加异常将作为“抑制异常”添加到基本异常中。您可以使用
baseException.getsupprested()
(Java7及更高版本!)获取它们


另请参见

如果你只是重新抛出异常,那么捕获它就没有意义。为什么你在捕获中抛出异常时甚至捕获?如果你只是重新抛出异常,那么捕获它就没有意义。为什么你在捕获中抛出异常时甚至捕获?我只是展示了不同的尝试捕获模式。异常处理显然取决于他打算如何处理捕获的异常。我只是展示了不同的try-catch模式。超出