正如关于虚拟扩展方法(默认方法)的官方声明所述:
虚拟扩展方法(默认方法)的目的是 使接口能够以兼容的方式进化 最初的出版物。“
我可以在JDK中看到一些很好的示例吗?
到目前为止,我已经在java.util.Collection
界面和其他几个界面中找到了,但是有一个更彻底的列表会更好。
编辑:我不是在寻找使用默认方法是否安全(因为我已经阅读了链接的问题)。我在JDK中寻找实际的例子。
答案 0 :(得分:2)
标准类中有几个地方我知道除了集合之外:
Java SQL API具有界面增强功能。 ResultSet.updateObject
,PreparedStatement.setObject
,PreparedStatement.executeLargeUpdate
(不同于executeUpdate
返回long
而不是int
)等等。默认情况下,它们会抛出UnsupportedOperationException
或其他一些异常。这就是“界面演变”:一种利用新功能增强旧界面的方法。
java.util.function
中的函数具有允许组合它们的默认方法。由于功能接口主要用于lambdas,因此不希望重新定义这些方法。这些方法只是为了方便。这不是“接口演化”,因为这些接口首先出现在Java 8中。但是这些方法是非默认的,您将无法用lambdas表达这些接口,因为违反了单抽象方法规则。
向java.util.Comparator
添加了几种默认方法:reversed()
,thenComparing()
等。默认实现也很好,通常不打算替换。这类似于函数,但之前存在Comparator
接口,所以它也是一种接口演化。
java.util.Spliterator
接口具有默认方法。这实际上是一个很好的例子,因为这里显示了不同目的的默认方法。默认情况下,getComparator()
方法会抛出,但如果spliterator使用SORTED
特征,则必须覆盖它。 hasCharacteristic()
方法只是一种使用非默认characteristics()
方法的便捷方法,可能永远不应该重新定义。 forEachRemaining()
默认实现将始终正常工作,但覆盖它可能会为某些分裂器产生更有效的结果。 getExactSizeIfKnown()
默认实现也始终正确,通常无需重新定义。但是,如果您的分裂器从未调整大小,您可以稍微优化它,只需返回-1
。