繁体   English   中英

流关闭模式的变种在Java中

[英]Variants of stream closing pattern in Java

在处理流时,我经常在Java文档和其他人的代码中看到以下模式:

FileInputStream fis = null;
try {
  fis = new FileInputStream("some.file");
  // do something useful with fis
} finally {
  if (fis != null) {
    fis.close();
  }
}

但我个人更喜欢不同的模式:

FileInputStream fis = new FileInputStream("some.file");
try {
  // do something useful with fis
} finally {
  fis.close();
}

我喜欢后者的简洁,我认为这是正确的。 但我对正确性是对的吗? 是否客观上有理由偏爱另一个?

更新

即使我写的例子几乎是我在现实生活中编写这样的代码,我的模式仍然更简洁。 比较文档方法:

public Object processFile(String fn) throws MyException {
  FileInputStream fis = null;
  try {
    fis = new FileInputStream(fn);
    return new Object(); // somehow derived from fis
  } catch (FileNotFoundException e) {
    throw new MySubExceptionForNotFound(e);
  } catch (IOException e) {
    throw new MySubExceptionForIoError(e);
  } finally {
    if (fis != null) {
      IOUtils.closeQuietly(fis);
    }
  }
}

用我的方法:

public Object processFile(String fn) throws MyException {
  try {
    FileInputStream fis = new FileInputStream(fn);
    try {
      return new Object(); // somehow derived from fis
    } finally {
      IOUtils.closeQuietly(fis);
    }
  } catch (FileNotFoundException e) {
    throw new MySubExceptionForNotFound(e);
  } catch (IOException e) {
    throw new MySubExceptionForIoError(e);
  }
}

我的一行更短! :d

有趣的是,如果你决定使用fis.close()而不是IOUtils.closeQuietly() ,我的代码不会改变,而“官方”代码将增长另外4行。

您发布的第二个示例不会尝试/捕获可能的错误... = new FileInputStream("..."); 如果加载文件失败将返回。 在第一个示例中,您可以自动捕获FileInputStream提供的错误。

我个人会选择第一个更好的错误处理。

除非从方法中抛出异常,否则第二个示例不会编译,因为FileNotFoundException是一个已检查的异常。

Compile.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
        FileInputStream fis = new FileInputStream("some.file");

第一个示例也不编译,因为您缺少相应的catch块。 这是一个编译示例。

import java.io.*;
public class Compile {

    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("some.file");
            // do something useful with fis

            if (fis != null) {
                fis.close();
            }
        }
        catch (FileNotFoundException fnf) {
        }
        catch (IOException ioe) {
        }
        finally {
        }
    }
}

使用try-with-resources

try (FileInputStream fis = new FileInputStream("some.file")) {
    // some code here
}

要回答推荐模式为何如此的问题,请考虑new FileInputStream(String)抛出一个您应该捕获的已检查异常的事实;

FileInputStream fis = null;
try {
    fis = new FileInputStream("somefile.txt");
} catch (FileNotFoundException e) {
    return false;
} finally {
    if (fis != null) {
        fis.close();
    }
}

允许您在与其他文件相关的异常相同的try / catch块中处理它。 与以下相比,它具有简洁和减少嵌套优势:

try {
    FileInputStream fis = new FileInputStream("some.file");
    try {
        // do something useful with fis
    } finally {
        fis.close();
    }
} catch (FileNotFoundException e) {
    return false;
}

如果你没有捕获异常而只是让它传播,那么你的建议就更清晰 - 但是由于在IO库中大量使用了检查异常(包括来自类构造函数),捕获和处理异常是很常见的,并且我认为只有一个模式用于教学目的而不是每次都向某人显示略有不同的模式是有意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM