Java 8 JDK 中是否有默认方法及其用法的好例子?
Are there any good examples of default methods and their usage in the Java 8 JDK?
关于虚拟扩展方法(默认方法)的官方声明指出:
The purpose of virtual extension methods (default methods) is to
enable interfaces to be evolved in a compatible manner after their
initial publication.”
我可以在 JDK 中看到一些很好的例子吗?
到目前为止,我已经在 java.util.Collection
界面和其他几个界面中找到了,但最好能有一个更详尽的列表。
编辑:我不是在寻找使用默认方法是否安全(因为我已经阅读了链接的问题)。我在 JDK.
中寻找实际示例
标准 类 中有几个地方我知道是在集合之外的:
Java SQL API 具有界面增强功能。添加了 ResultSet.updateObject
、PreparedStatement.setObject
、PreparedStatement.executeLargeUpdate
(不同于 executeUpdate
返回 long
而不是 int
)等。默认情况下,它们会抛出 UnsupportedOperationException
或其他一些异常。这是 "interface evolution":一种使用新功能增强旧界面的方法。
java.util.function
中的函数具有允许组合它们的默认方法。这些方法预计不会被重新定义,因为功能接口主要用于与 lambda 一起使用。这些方法只是为了方便。这不是 "interface evolution",因为这些接口首先出现在 Java 8 中。但是,如果这些方法不是默认方法,您将无法使用 lambda 表达这些接口,因为单一抽象方法规则是违反了。
java.util.Comparator
增加了几个默认方法:reversed()
、thenComparing()
等。默认实现也很好,通常不会被替换。这和函数类似,但是Comparator
之前就有接口,所以也是一种接口演化。
java.util.Spliterator
接口有默认方法。这实际上是一个很好的例子,因为这里显示了不同目的的默认方法。 getComparator()
方法默认会抛出异常,但如果 spliterator 使用 SORTED
特性,则必须覆盖它。 hasCharacteristic()
方法只是使用非默认 characteristics()
方法的一种便捷方式,可能永远不应该重新定义。 forEachRemaining()
默认实现将始终正常工作,但覆盖它可能会为某些拆分器产生更有效的结果。 getExactSizeIfKnown()
默认实现也总是正确的,通常不需要重新定义它。但是,如果您的拆分器从未确定大小,您可以对其进行一些优化,只需返回 -1
.
关于虚拟扩展方法(默认方法)的官方声明指出:
The purpose of virtual extension methods (default methods) is to enable interfaces to be evolved in a compatible manner after their initial publication.”
我可以在 JDK 中看到一些很好的例子吗?
到目前为止,我已经在 java.util.Collection
界面和其他几个界面中找到了,但最好能有一个更详尽的列表。
编辑:我不是在寻找使用默认方法是否安全(因为我已经阅读了链接的问题)。我在 JDK.
中寻找实际示例标准 类 中有几个地方我知道是在集合之外的:
Java SQL API 具有界面增强功能。添加了
ResultSet.updateObject
、PreparedStatement.setObject
、PreparedStatement.executeLargeUpdate
(不同于executeUpdate
返回long
而不是int
)等。默认情况下,它们会抛出UnsupportedOperationException
或其他一些异常。这是 "interface evolution":一种使用新功能增强旧界面的方法。java.util.function
中的函数具有允许组合它们的默认方法。这些方法预计不会被重新定义,因为功能接口主要用于与 lambda 一起使用。这些方法只是为了方便。这不是 "interface evolution",因为这些接口首先出现在 Java 8 中。但是,如果这些方法不是默认方法,您将无法使用 lambda 表达这些接口,因为单一抽象方法规则是违反了。java.util.Comparator
增加了几个默认方法:reversed()
、thenComparing()
等。默认实现也很好,通常不会被替换。这和函数类似,但是Comparator
之前就有接口,所以也是一种接口演化。java.util.Spliterator
接口有默认方法。这实际上是一个很好的例子,因为这里显示了不同目的的默认方法。getComparator()
方法默认会抛出异常,但如果 spliterator 使用SORTED
特性,则必须覆盖它。hasCharacteristic()
方法只是使用非默认characteristics()
方法的一种便捷方式,可能永远不应该重新定义。forEachRemaining()
默认实现将始终正常工作,但覆盖它可能会为某些拆分器产生更有效的结果。getExactSizeIfKnown()
默认实现也总是正确的,通常不需要重新定义它。但是,如果您的拆分器从未确定大小,您可以对其进行一些优化,只需返回-1
.