0

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此功能的原因。

4

2 回答 2

3

Java 总是尽力向后兼容。这是当今语言几乎所有奇怪或不幸方面的原因。这已经发生了好几次了,但是引入一个新的关键字,比如withor using,并不是一个轻率的决定。如果他们引入了一个新关键字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是合乎逻辑的快乐媒介。


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

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

于 2018-06-21T17:32:06.547 回答
2

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

try-with-resources不重用-概念,而是try-概念。虽然很少见,但有它的用途。例如,您可以不显式捕获异常并重新抛出它,而只需在-block 中进行一些清理。1catchtryfinallytry-finallyfinally

AutoCloseable资源的性质非常适合这个用例:打开一个AutoCloseable资源,做某事,最后关闭它,无论如何。

有人可能会争辩说,通过 a 开始这个过程try似乎是人为的。然而,这是语言委员会的设计决定,因此无需辩论。如果我不得不猜测,我会选择Michael 的论点,并说他们不想引入新的关键字来保持向后兼容。


1我知道@Radiodef 指出的事实,即 atry-with-resources将被翻译成 atry-catch-finally。然而,从我的角度来看,这是一个实现细节和一个指定行为的工具。这对于理解语义不是必需的。

于 2018-06-21T17:39:03.067 回答