尝试转让所有权
Posted
技术标签:
【中文标题】尝试转让所有权【英文标题】:Try-with transfer ownership 【发布时间】:2014-05-30 21:44:47 【问题描述】:在 Java 7 中,有一种 try-with 语法可确保 InputStream 等对象在所有代码路径中都关闭,而不管异常情况如何。但是,在 try-with 块中声明的变量(“is”)是 final 的。
try (InputStream is = new FileInputStream("1.txt"))
// do some stuff with "is"
is.read();
// give "is" to another owner
someObject.setStream(is);
// release "is" from ownership: doesn't work because it is final
is = null;
在 Java 中是否有简洁的语法来表达这一点?考虑这种异常不安全的方法。添加相关的 try/catch/finally 块会使方法更加冗长。
InputStream openTwoFiles(String first, String second)
InputStream is1 = new FileInputStream("1.txt");
// is1 is leaked on exception
InputStream is2 = new FileInputStream("2.txt");
// can't use try-with because it would close is1 and is2
InputStream dual = new DualInputStream(is1, is2);
return dual;
显然,我可以让调用者打开这两个文件,将它们都放在一个 try-with 块中。这只是我想在将资源的所有权转移给另一个对象之前对资源执行一些操作的情况的一个示例。
【问题讨论】:
为什么需要释放is
?它仅适用于 try 块。
尝试对您的情况无济于事。 try-with 旨在用于识别的资源绝不能持续存在于 try 块范围之外的情况。这绝不适用于您的情况
【参考方案1】:
try-with 旨在用于已识别资源绝不能持续存在于 try 块范围之外的情况。
如果你想使用 try-with 结构,你必须改变你的设计如下:
-
删除
openTwoFiles()
方法。它是免费的。
为DualInputStream
类创建一个构造函数,它接受两个文件名并创建两个InputStreams
。声明这个构造函数抛出IOException
并允许它抛出IOExceptions
。
在 try-with 构造中使用新的构造函数。
【讨论】:
openTwoFiles 方法就是一个例子。如果我让 DualInputStream 构造函数接受文件名,那么在构造函数实现中我仍然会遇到所有异常安全问题。 构造函数没有异常安全问题。任何 IOException 都会使构造函数溢出,并且对象将被清理。你不会在构造函数中捕获异常。 那是不真实的。如果我在 DIS 构造函数中打开了两个 InputStream 并且在打开第二个流时发生了异常,那么第一个流将被泄漏,除非我编写了冗长而冗长的代码来处理这种情况。以上是关于尝试转让所有权的主要内容,如果未能解决你的问题,请参考以下文章