finally { if (inputStream != null) { inputStream.close();

finally { if (inputStream != null) { inputStream.close();

我不知道怎么理解这个:

{
        if (inputStream **!= null**) {
            inputStream.close();

来自那个例子:

public class CopyLines {
public static void main(String[] args) throws IOException {

    BufferedReader inputStream = null;
    PrintWriter outputStream = null;

    try {
        inputStream = new BufferedReader(new FileReader("xanadu.txt"));
        outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));

        String l;
        while ((l = inputStream.readLine()) != null) {
            outputStream.println(l);
        }
    } finally {
        if (inputStream != null) {
            inputStream.close();
        }
        if (outputStream != null) {
            outputStream.close();
        }
    }
}}

当提供任何数据时,inputStream 正在关闭???

这意味着每当 try 块完成(成功与否)时,它将尝试关闭 finally 块中的流(inputStreamoutputStream),但是作为try 块在创建 BufferedReaderPrintWriter 的实例时可能会失败,您需要先检查它是否不是 null 否则您将得到一个 NPE。

您可以考虑使用 try-with-resouces 语句来避免必须检查是否 null 并显式调用 close() 这样可以大大简化您的代码。

try (BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
     PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt")) {
    // your code here
}

那只是为了避免空指针异常。仅当对象不是 null.

时才调用函数

简单来说,close 函数仅在对象不为 null 时调用,否则如果您对具有 null 值的对象调用 close(),您将遇到 null pointer exception

有趣的是finally的用法,不管有没有异常,总是被调用。

当执行到 finally 块时,首先检查 inputstreamoutputstream 是否为空,然后关闭两个流以释放资源。

请参阅 link 以检查最终尝试:https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2

如果你问为什么这段代码在 finally 块中,那么,

这只是为了确保 inputStreamoutputStream 将始终关闭,无论上面的代码是否遇到异常。

怎么不一样

区别在于任何异常期间。如果发生任何异常,那么它不会简单地返回,而是确保在将异常返回给调用此方法的方法之前关闭两个流。

因为 java 的 finally 块总是被执行,除非:

  • System.exit 被称为
  • 或 JVM 崩溃

这是一种常见的做法,可以关闭 finally 块中的流、数据库或任何其他类似连接。这确保连接始终关闭。因为如果它们不在 finally 块中,并且系统不断遇到一些 Excpetion 那么它最终将 运行 失去连接。