此article中声称:
在其中引入
default
方法的主要原因之一 接口是为了增强Java 8中的Collections API以支持 lambda表达式。
我可以理解@FunctionalInterface
的帮助是说只有一种抽象方法,而lambda应该代表这种特定方法。
但是default
方法如何帮助支持lambda?
答案 0 :(得分:34)
以Collection.forEach
方法为例,该方法旨在采用Consumer
功能接口的实例,并且在Collection
接口中具有默认实现:
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
如果JDK设计人员没有引入默认方法的概念,那么Collection
接口的所有实现类都必须实现forEach
方法,因此切换到Java会出现问题- 8而不会破坏您的代码。
因此,为了促进lambda的采用和Consumer
,Supplier
,Predicate
等新功能接口的使用,JDK设计人员引入了默认方法的概念来提供向后兼容,现在无需进行任何更改即可更轻松地切换到Java-8。
如果您不喜欢界面中的默认实现,则可以覆盖它并提供自己的实现。
答案 1 :(得分:14)
他们间接地提供了帮助:借助removeIf()
,stream()
等附加方法,您可以在集合上使用lambda。
如果未将这些方法添加为集合中的默认方法,则这些方法不能完全破坏现有集合的实现。
答案 2 :(得分:4)
在默认情况下,默认方法可以帮助自己的另一情况是它们自身的功能接口。以Function<T,R>
界面为例,您真正关心的唯一方法是R apply(T t)
,因此当您需要在某个地方使用Function
时,可以传递一个lambda并将创建一个{{1 }}实例,其中该lambda方法是Function
方法。
但是,一旦拥有一个apply
实例,就可以调用其他有用的方法,例如Function
,这些方法在其上组合了函数。默认实现只是简单地链接函数,但是如果您创建自己的实现<V> Function<T,V> andThen(Function<? super R,? extends V> after)
接口的类,则可以覆盖它。
简而言之,默认方法为您提供了一种从具有附加方法的功能接口创建lambda的简便方法,同时还为您提供了使用完整类覆盖这些附加方法的选项。