代码之家  ›  专栏  ›  技术社区  ›  Sam

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

  •  2
  • Sam  · 技术社区  · 7 年前

    这是我的第一个代码:

    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);
            //...
        }
    }
    

    我的问题: 为什么第二段代码中有编译器错误? 我不能使用函数接口的静态方法的方法引用吗?

    我知道我不能将方法引用与函数接口的默认方法一起使用。

    等级

    • 类::instanceMethod

    • 实例::instanceMethod

    • 类::新建

    功能接口

    谢谢!

    2 回复  |  直到 7 年前
        1
  •  6
  •   Michael    7 年前

    Comparator.reverseOrder() Comparator 输入,因为这是它返回的。

    Comparator::reverseOrder 是一个表达式,解析为 一种方法 它不带参数,返回 比较器 e、 通用航空公司 Supplier<Comparator<String>> ,尽管它可以是任何匹配的函数接口。

    在第二个实例中,您试图传递一个方法(它提供 比较器 )作为论据。这个方法不需要这个-它只需要 比较器 它自己。

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

    s.sorted(new Comparator())
    

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

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

    如果我们声明以下方法:

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

    然后我们可以用方法引用来调用它

    giveMeAComparatorSupplier(Comparator::reverseOrder);
    

    (请注意,您的方法引用语法是错误的-它从不使用 () )

        2
  •  3
  •   rgettman    7 年前

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

    第二,市场 sorted 方法需要 Comparator 比较器 . 这个方法需要一个 比较器 比较器 需要时。

    这与 比较器 是一个接口;通常可以创建对 static 接口方法。这跟 已排序 需要一个实际的 实例,而不是函数接口的实例,此时可以提供方法引用。

    所以即使去掉括号,它仍然无法编译。只有第一个代码,它直接传递 ,将按预期编译和工作。