【问题标题】:Why does AutoClosaeble use try/catch semantics?为什么 AutoClosaeble 使用 try/catch 语义?
【发布时间】:2018-06-21 17:12:07
【问题描述】:

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 重新用于此功能的原因。

【问题讨论】:

  • 它不重用try/catch语义,而是try/finally语义。
  • 这仍然被认为是题外话,除非其中一位 Java 开发人员可能会过来回答这个非常具体的问题
  • “try 暗示您希望主体在某一时刻抛出异常” - 不,这不再是真的。它被称为 try-with-resource 并简单地“重用”try 关键字,这很好,因为您可以在同一个结构中处理异常,而不必以某种方式嵌套它们。
  • "// 我知道,C# 语法" - 在这种情况下哀叹 C# 语法有点讽刺。在 C# 中所做的一切只是掩盖了 try/finally 的幕后创建。在这个过程中,重载一个已经用于完全不同的东西(在不同的上下文中)的关键字using。 Java 只是更多地暴露底层结构,而不是创建或重载不必要的关键字。

标签: java java-7 autocloseable


【解决方案1】:

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 作为类型 名字。)

【讨论】:

    【解决方案2】:

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

    try-with-resources 不重用 try-catch 概念,而是重用 try-finally 概念。虽然很少见,try-finally 有它的用途。例如,您可以不显式捕获异常并重新抛出它,而只需在 finally-block 中进行一些清理。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。然而,从我的角度来看,这是一个实现细节和一个指定行为的工具。这对于理解语义不是必需的。

    【讨论】:

    • 谢谢。对我来说,“尝试”这个词并不是说“创建一个资源并在我完成后处理它”。因此问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多