是否可以将方法引用与接口的静态方法一起使用?



这是我的第一个代码:

public class MethodReference {
public static void main (String []args) {
Stream<String> s = Stream.of("brown bear", "grizzly");
s.sorted(Comparator.reverseOrder()).forEach(System.out::print);
//...
}
}

结果:灰棕熊

这是我的第二个代码:

public class MethodReference {
public static void main (String []args) {
Stream<String> s = Stream.of("brown bear", "grizzly");
s.sorted(Comparator::reverseOrder()).forEach(System.out::print);
//...
}
}

结果:编译器错误

我的问题: 为什么第二个代码中会出现编译器错误? 我不能将方法引用用于功能接口的静态方法吗?

我知道我不能将方法引用与功能接口的默认方法一起使用。 我知道我可以在 5 种情况下将方法引用与类一起使用:

  • 类::静态方法

  • 类::实例方法

  • 实例:
  • :实例方法

  • 类别::新

功能接口

  • 接口::抽象方法

多谢!

>Comparator.reverseOrder()是一个解析为Comparator类型的表达式,因为这就是它返回的内容。

Comparator::reverseOrder是一个表达式,它解析为一个不带参数并返回Comparator例如Supplier<Comparator<String>>的方法,尽管它可以是任何匹配的函数接口。

在第二个实例中,您尝试传递一个方法(提供Comparator(作为参数。该方法不想要那个 - 它只想要Comparator本身。

你可以这样想(只是伪代码来证明这一点(:

s.sorted(new Comparator())

s.sorted(new Supplier(new Comparator()))

回答您的第二个问题,即是否可以将方法引用用于接口的静态方法 - 是的,绝对!

如果我们声明以下方法:

<T> void giveMeAComparatorSupplier(Supplier<Comparator<T>> supplier) { }

那么我们绝对可以用方法引用来调用它

giveMeAComparatorSupplier(Comparator::reverseOrder);

(仅供参考,您的方法引用语法是错误的 - 它从不使用()(

你的第二个代码有两点问题。 首先,方法引用根本不使用括号或参数。 您只需要提供稍后将调用的方法;此时您没有调用该方法。

其次,sorted方法需要一个Comparator,而不是一个提供Comparator的功能接口。 该方法需要一个已经创建并准备就绪的Comparator,而不是在需要时提供Comparator的功能接口。

它与Comparator是一个接口这一事实无关;通常可以创建对static接口方法的方法引用。 它与以下事实有关:sorted需要一个实际的Comparator实例,而不是函数接口的实例,这时你可以提供方法引用。

因此,即使您去掉括号,它仍然无法编译。 只有直接传递Comparator的第一个代码才能按预期编译和工作。

最新更新