Understand the compile time error with Method Reference

雨燕双飞 提交于 2021-01-04 06:41:39

问题


As per the Documentation, Method Reference is absolutely not a static call. It works on both static and non- static methods. When we define our own non-static method in a given class and try to use it using Method Reference then the compile-time-error "cannot make static reference to non static method" is NOT seen in case of Function but only seen in case of Supplier, Consumer and Predicate. Why is that so?

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

回答1:


You have to follow both the return type and the formal parameter type of the Student method and use the appropriate functional interface.


private Supplier<Integer> s = Student::supply; // compile-time error

The Supplier<T> consumes nothing and returns T. An example would be:

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

The relevant functional interface for the method reference Student::supply is Function<T, R>. The both following are equal:

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<Integer> p1= Student::check; //compile-time error

The very same issue but Predicate<T> consumes T and returns Boolean.

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

You can use BiPredicate<T, R> that results in Boolean if you want to use Student::check method reference:

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

private Consumer<Integer> c= Student::consume; / compile-time error

Again nothing new, Consumer<T> consumes T and returns nothing (the return type is void).

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

The method reference Student::consume is suitable for BiConsumer consuming both Student and some Integer:

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


来源:https://stackoverflow.com/questions/61842848/understand-the-compile-time-error-with-method-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!