我可能会过度思考这个问题,但我只是写了代码:
try (InputStream in = ModelCodeGenerator.class.getClassLoader().getResourceAsStream("/model.java.txt"))
{
modelTemplate = new SimpleTemplate(CharStreams.toString(new InputStreamReader(in, "ascii")));
}
Run Code Online (Sandbox Code Playgroud)
这意味着InputStreamReader永远不会关闭(但在这种情况下,我们知道它的close方法只是关闭底层的InputStream.)
人们可以把它写成:
try (InputStreamReader reader = new InputStreamReader(...))
Run Code Online (Sandbox Code Playgroud)
但这似乎更糟糕.如果由于某种原因抛出InputStreamReader,则InputStream将永远不会被关闭,对吧?这是C++中的常见问题,其中构造函数调用其他构造函数.异常可能导致内存/资源泄漏.
这里有最好的做法吗?
fge*_*fge 12
这意味着InputStreamReader永远不会关闭
嗯?在你的代码中......它肯定会处理资源流的.close().请参阅下面的更多细节...
正如@SotiriosDelimanolis所提到的,您可以在try-with-resources语句的"资源块"中声明多个资源.
你在这里有另一个问题:.getResourceAsStream()可以返回null; 因此,您可能拥有NPE.
如果我是你,我会这样做:
final URL url = ModelCodeGenerator.class.getClassLoader()
.getResource("/model.java.txt");
if (url == null)
throw new IOException("resource not found");
try (
final InputStream in = url.openStream();
final Reader reader = new InputStreamReader(in, someCharsetOrDecoder);
) {
// manipulate resources
}
Run Code Online (Sandbox Code Playgroud)
但是有一点非常重要,需要考虑 ......
Closeable确实延伸AutoCloseable,是的; 实际上它只是抛出(IOExceptionvs Exception)异常,"签名明智" .但行为存在根本差异.
从javadoc AutoCloseable的.close()(强调我的):
请注意,与Closeable的close方法不同,此close方法不需要是幂等的.换句话说,不止一次调用此close方法可能会产生一些可见的副作用,这与Closeable.close不同,如果多次调用则需要它无效.但是,强烈建议强制使用此接口的实现者使其close方法具有幂等性.
事实上,javadoc Closeable很明显:
关闭此流并释放与其关联的所有系统资源.如果流已经关闭,则调用此方法无效.
你有两个非常重要的观点:
Closeable还负责处理与之相关的所有资源; 所以,如果你关闭一个BufferedReader包裹了一个包裹的Reader包裹InputStream,那三个都关闭了;.close()不止一次打电话,没有进一步的副作用.当然,这也意味着您可以选择偏执选项并保留对所有 Closeable资源的引用并将它们全部关闭; 但要注意你是否有AutoCloseable资源混合而不是Closeable!
但这似乎更糟。如果
InputStreamReader由于某种原因抛出,则InputStream永远不会关闭,对吗?
没错(虽然不太可能,但InputStreamReader构造函数实际上并没有做太多事情)。
在try-with-resources允许声明尽可能多的资源,只要你愿意。为包装的资源声明一个,为InputStreamReader.
try (InputStream in = ModelCodeGenerator.class
.getClassLoader()
.getResourceAsStream("/model.java.txt");
InputStreamReader reader = new InputStreamReader(in)) {...}
Run Code Online (Sandbox Code Playgroud)
请注意,getResourceAsStream可能会返回null,这会导致InputStreamReader构造函数抛出NullPointerException. 如果您想以不同的方式处理该问题,请调整检索要包装的资源的方式。
上面链接的教程展示了这个例子
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
Run Code Online (Sandbox Code Playgroud)
与解释
在此示例中,try-with-resources 语句包含两个用分号分隔的声明:
ZipFile和BufferedWriter。当直接跟随它的代码块终止时,无论是正常情况还是由于异常,都将按此顺序自动调用BufferedWriter和ZipFile对象的关闭方法。请注意,资源的 close 方法以其创建的相反顺序调用。
| 归档时间: |
|
| 查看次数: |
8006 次 |
| 最近记录: |