开放流try/finally块的Java代码样式

Pat*_*ick 10 java coding-style

这是一个代码风格的问题.我注意到很多示例代码,包括Oracle的一些示例,确保以下列方式关闭流:

InputStream in = null;
try {
    in = acquireStream();
    ...
} finally {
    if (in != null) in.close();
}
Run Code Online (Sandbox Code Playgroud)

请注意初始化为null并检查finally块中的null .

我倾向于编写这样的代码:

InputStream in = acquireStream();
try {
    ...
} finally {
    in.close();
}
Run Code Online (Sandbox Code Playgroud)

两种方法都有优点或缺点吗?我喜欢我的风格,因为我不需要空检查.我也想尽可能避免null.但由于Oracle风格在在线示例中非常常见,我想知道我的是否有一些隐藏的错误.

我问同样的问题为InputStream,OutputStream,java.sql.Connection,java.sql.PreparedStatement,等我倾向于获取的外界资源try块,然后关闭它在finally没有空校验.除了文体差异,还有什么我想念的吗?

谢谢.

dar*_*jan 8

Java 7开始,有一种更好的方法可以在Closeable资源方面编写try-finally块.

现在,您可以在try关键字后的括号中创建资源,如下所示:

try (init resources) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

他们将被关闭automcatically的代码块结束后.没有必要在finally块中关闭流.

一个例子:

try (
   ZipFile zf = new ZipFile(zipFileName);
   BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset);
) {
    // Enumerate each entry
    for (Enumeration entries = zf.entries(); entries.hasMoreElements();) {
        // Get the entry name and write it to the output file
        String newLine = System.getProperty("line.separator");
        String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine;
        writer.write(zipEntryName, 0, zipEntryName.length());
    }
}
Run Code Online (Sandbox Code Playgroud)

而经过for循环完成,资源将被关闭!


ILM*_*tan 6

答案是,不,这样做没有隐藏的错误.这纯粹是一种风格的东西.我通常从来没有尝试catch finally块,只尝试catch块并尝试finally块.

他们往往看起来像这样:

try {
    InputStream in = acquireStream();
    try {
        ...
    } finally {
        in.close();
    }
} catch (IOException e) {
    ... handle exception
}
Run Code Online (Sandbox Code Playgroud)

没有理由将acquireStream()放在try finally块中.如果in从未分配给有效的流,则永远不能关闭它.显式空检查完全没必要.此外,您很少想要在close()上处理异常,而不是主处理块中的异常.


Ami*_*ani 3

通常你拥有的是try,,catchfinally在这种情况下,使用标准 SUN 方法是有利的,因为您可以捕获 、 内部发生的任何acquireStream()错误trycatch