【问题标题】:Is it possible to use method reference with static method of interface?是否可以将方法引用与接口的静态方法一起使用?
【发布时间】:2019-03-15 19:23:56
【问题描述】:

这是我的第一个代码:

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 种情况下对类使用方法引用:

  • 类::staticMethod

  • 类::instanceMethod

  • instance::instanceMethod

  • 类::新

功能界面

  • 接口::abstractMethod

非常感谢!

【问题讨论】:

  • Comparator::reverseOrder() - 这在你的第二个代码 sn-p 中可能是错误的
  • Comparator::reverseOrder() 方法引用没有括号 - 永远
  • 你需要研究一下方法参考是什么。
  • I know I can't use method reference with default method of functional interface。这是错误的。你可以有即Function::andThen,其中Function是一个功能接口,andThen是一个默认方法。

标签: java lambda method-reference


【解决方案1】:

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

Comparator::reverseOrder 是一个表达式,它解析为 一个方法,它不接受任何参数并返回一个 Comparator 例如Supplier&lt;Comparator&lt;String&gt;&gt;,尽管它可以是任何匹配的功能接口。

在第二种情况下,您尝试将方法(提供Comparator)作为参数传递。该方法不想要那个 - 它只想要 Comparator 本身。

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

s.sorted(new Comparator())

对比

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

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

如果我们声明如下方法:

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

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

giveMeAComparatorSupplier(Comparator::reverseOrder);

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

【讨论】:

    【解决方案2】:

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

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

    这与Comparator是一个接口无关;通常可以创建对static 接口方法的方法引用。这与sorted 需要一个实际的Comparator 实例而不是功能接口的实例有关,此时您可以提供方法引用。

    所以即使你去掉括号,它仍然不会编译。只有您的第一个代码直接传递了Comparator,才能按预期编译和工作。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 2014-08-06
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多