为什么AutoClosaeble使用try / catch语义?

时间:2018-06-21 17:12:07

标签: java java-7 autocloseable

Java的AutoCloseable功能“重用” try / catch语义:

try (Stream x = ...) {
    // work with x
}

// x is out of scope and was auto-closed

我很好奇为什么他们没有为此新功能引入新的语义。 try表示您希望主体在某一点或另一点抛出异常(或可能会抛出异常)。对我而言,这与“实例化该资源并在完成后将其关闭”大不相同。这与处理异常没有任何关系。为什么不这样呢?

with (Stream x = ...) { ... }

using (Stream x = ...) { ... } // I know, C# syntax

我不想引起争论,我想知道Java团队决定为此功能重新使用try的原因。

2 个答案:

答案 0 :(得分:3)

Java始终尽力向后兼容。这是当今语言几乎所有奇怪或不幸的方面的原因。 It's happened a handful of times,但引入诸如withusing之类的新关键字并不是要轻率的决定。如果他们引入了新的关键字using,则诸如int using = 0之类的旧代码将无法针对Java *的最新版本进行编译。

基本上引入了

try-with-resources来减少以下常见模式的冗长性:

SomeResource resource;
try {
    resource = new Resource();
    resource.foo();
}
//optional catch
finally {
    if (resource != null) resource.close();
}

因为try之前已经涉及到,所以向try添加附加功能是合乎逻辑的。


*有趣的是,进行了类似的讨论over Java 10's var,它实际上不是关键字,而是“保留类型名称”(因此语义略有不同):

  

风险:源代码不兼容(可能有人使用var作为类型   名称。)

答案 1 :(得分:2)

问题部分是关于Java语言的设计选择的。由于问题的性质,此答案只是问题的部分答案。

try-with-resources不会重用try-catch概念,而会重用try-finally概念。尽管很少见,try-finally有其用途。例如,您可以代替显式捕获异常并重新引发它,而只需在finally块中进行一些清理。 1

AutoCloseable resources的性质非常适合此用例:打开AutoCloseable资源,执行任何操作,最后不管如何关闭它。

有人可能会争辩说,通过try启动此过程似乎是人为的。但是,这是语言承诺的设计决定,因此不值得争论。如果我不得不猜测,我会选择Michael's line of argumentation,说他们不想引入新的关键字来保持向后兼容。


1 我知道pointed out by @Radiodeftry-with-resources will be translated to a try-catch-finally的事实。但是,从我的角度来看,这是一个实现细节,也是一个指定行为的工具。理解语义并不是必需的。