【问题标题】:finally { if (inputStream != null) { inputStream.close();最后 { if (inputStream != null) { inputStream.close();
【发布时间】:2016-12-28 01:55:19
【问题描述】:

我不知道怎么理解:

{
        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 正在关闭???

【问题讨论】:

标签: java bufferedreader ioexception


【解决方案1】:

这意味着每当 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
}

【讨论】:

  • 好的。根据 Java 文档,我是否理解正确:readline() 读取一行,如果它以 \n (或任何其他适合此方法的内容)结尾,则方法停止读取并返回null,因此 JVM 处理此过程正确并且最终不会发生资源泄漏?有可能在行读取期间发生一些 i/o 错误并且读取也没有正确完成 winh null,然后 finally 块完成他的工作?
  • 我不确定,我明白你的意思,但实际上它会关闭流,无论发生什么都会防止泄漏
  • 我试图了解 readLine() 是如何工作的。根据JavaDocs,我不确定是否正确结束了readLine(),当读取任何行尾指示符时,以null结尾,将其解析为JVM,或者仅当我们遇到以下情况时才将其解析为JVM没有读取任何行的 EOF...
  • 如果 readLine 返回 null 结尾的 null 是变量 l 而不是流
  • 无论是否返回readLine null,流实例都不会为null,因此它将按预期在finally块中关闭
【解决方案2】:

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

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

有什么不同。

区别在于任何异常期间。如果发生任何异常,则不是简单地返回,而是确保两个流都关闭,然后再将异常返回给调用该方法的方法。

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

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

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

【讨论】:

  • 不,我对 finally 块不感兴趣。只有!=null 让我感兴趣。
【解决方案3】:

这只是为了避免空指针异常。仅当对象不是null 时才调用函数。

简单来说,close 函数只在对象不为空时调用,否则如果你在具有空值的对象上调用close(),你会遇到null pointer exception

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

【讨论】:

    【解决方案4】:

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

    请参阅链接以检查有关 finally 的尝试:https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2

    【讨论】:

      猜你喜欢
      • 2011-08-21
      • 2014-08-07
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      相关资源
      最近更新 更多