【问题标题】:Understand the compile time error with Method Reference使用方法参考了解编译时错误
【发布时间】:2020-05-16 20:02:58
【问题描述】:

根据文档,方法参考绝对不是静态调用。它适用于静态和非静态方法。 当我们在给定类中定义自己的非静态方法并尝试使用方法引用使用它时,编译时错误“无法对非静态方法进行静态引用”在 Function 的情况下不可见,而仅在情况下可见供应商、消费者和谓词。为什么会这样?

class Demo{
    private Function<Student, Integer> p= Student::getGradeLevel; // fine
    private Supplier<Integer> s = Student::supply; // compile-time error
    private Predicate<Integer> p1= Student::check; //compile-time error
    private Consumer<Integer> c=  Student::consume; / compile-time error
    private Function<String, String> f1 = String::toUpperCase; //fine
}

class Student{
    public int getGradeLevel() {
        return gradeLevel;
    }

    public boolean check(int i) {
        return true;
    }

    public int supply() {
        return 1;
    }

    public void consume(int i) {
        System.out.println(i);
    }
}

【问题讨论】:

  • 我建议您访问official documentation about types of method references。第一行代码之所以编译,是因为它可以表示student -&gt; student.getGradeLevelStudent类型的实例方法。与使用 Function 相关时,这很容易理解,因为那是您使用 p.apply(&lt;the arbitrary object&gt;) 的时候。

标签: java lambda java-8 method-reference functional-interface


【解决方案1】:

你必须同时遵循Student方法的返回类型和形参类型,并使用适当的函数接口。


private Supplier&lt;Integer&gt; s = Student::supply; // compile-time error

Supplier&lt;T&gt; 消耗 nothing 并返回 T。一个例子是:

Student student = new Student();
Supplier<Integer> s = () -> student.supply();

方法参考Student::supply的相关功能接口为 Function&lt;T, R&gt;。以下两者相等:

Function<Student, Integer> function = student -> student.supply();
Function<Student, Integer> function = Student::supply;

// You have already used a method reference with the very same return and parameter types
Function<Student, Integer> p = Student::getGradeLevel;

private Predicate&lt;Integer&gt; p1= Student::check; //compile-time error

同样的问题,但Predicate&lt;T&gt; 消耗 T 并返回Boolean

Student student = new Student();
Predicate<Integer> p =  i -> student.check(i);

如果你想使用Student::check方法参考,你可以使用BiPredicate&lt;T, R&gt;导致Boolean

BiPredicate<Student, Integer> biPredicate = (student, integer) -> student.check(integer);
BiPredicate<Student, Integer> biPredicate = Student::check;

private Consumer&lt;Integer&gt; c= Student::consume; / compile-time error

再次没有什么新鲜事,Consumer&lt;T&gt; 消耗 T 并返回 nothing(返回类型为 void)。

Student student = new Student();
Consumer<Integer> c = integer -> student.consume(integer);

方法参考Student::consume适用于BiConsumer同时使用Student和一些Integer

BiConsumer<Student, Integer> biConsumer = (student, integer) -> student.consume(integer);
BiConsumer<Student, Integer> biConsumer = Student::consume;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    相关资源
    最近更新 更多