【问题标题】:Are there any good examples of default methods and their usage in the Java 8 JDK?Java 8 JDK中是否有默认方法及其用法的好例子?
【发布时间】:2015-08-03 11:57:40
【问题描述】:

正如官方关于虚拟扩展方法(默认方法)的声明:

虚拟扩展方法(默认方法)的目的是 使接口在它们之后以兼容的方式演进 初次发表。”

我可以在 JDK 中看到一些很好的例子吗? 到目前为止,我已经在java.util.Collection 界面和其他几个界面中找到了,但如果有一个更完整的列表会很好。

编辑:我不是在寻找使用默认方法是否安全(因为我已经阅读了链接的问题)。我正在寻找JDK中的实际示例。

【问题讨论】:

  • 谁说它们的使用是反模式?你?为什么使用它们是一种反模式?由于语言设计者自己说它们的使用有有效的用例,所以它们不是反模式,你的话对我来说是空洞的。
  • 我仍然信任 Brian Goetz。
  • 是的,这也是我链接的答案。它为默认方法陈述了 4 个有效用例。

标签: java java-8 default-method


【解决方案1】:

除了集合之外,我还知道标准类中有几个地方:

  • Java SQL API 具有接口增强功能。增加了ResultSet.updateObjectPreparedStatement.setObjectPreparedStatement.executeLargeUpdate(不同于executeUpdate返回long而不是int)等等。默认情况下,它们会抛出 UnsupportedOperationException 或其他一些异常。这就是“界面演变”:一种用新功能增强旧界面的方法。

  • java.util.function 中的函数具有允许组合它们的默认方法。这些方法预计不会被重新定义,因为函数式接口主要用于 lambdas。这些方法只是为了方便。这不是“接口演变”,因为这些接口首先出现在 Java 8 中。但是,如果这些方法不是默认的,您将无法使用 lambdas 来表达这些接口,因为会违反单一抽象方法规则。

  • java.util.Comparator 中添加了几个默认方法:reversed()thenComparing() 等等。默认实现也很好,通常不打算被替换。这类似于函数,但Comparator接口之前存在,所以它也是一种接口进化。

  • java.util.Spliterator 接口具有默认方法。这实际上是一个很好的例子,因为这里显示了不同目的的默认方法。 getComparator() 方法默认抛出,但如果拆分器使用 SORTED 特性,则必须覆盖它。 hasCharacteristic() 方法只是使用非默认 characteristics() 方法的一种方便方式,可能永远不应该重新定义。 forEachRemaining() 默认实现将始终正常工作,但覆盖它可能会为某些拆分器产生更有效的结果。 getExactSizeIfKnown() 默认实现也总是正确的,通常不需要重新定义它。但是,如果您的拆分器从未调整大小,您可以对其进行一些优化,只需返回 -1

【讨论】:

  • 还有一个更明显的例子:Iterator.remove()。迭代器在 Java 8 中获得了抛出 UOE 的默认值,有效地使该方法成为可选方法(无论如何,99% 的非 JDK 实现都只是抛出 UOE。)
  • @BrianGoetz,我想提一下,但出于某种原因,我认为 OP 提到的“其他几个”包括Iterator。可能这只是我的想象。
  • 我要指出,事后看来,如果这些功能接口可以扩展(它们是,@ 987654342@ 扩展Function)。我们甚至可能会弃用这些特定的默认方法。 (与任何工具一样,用户可能会犯错误,有时甚至专家也会犯错。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 2023-04-04
相关资源
最近更新 更多