无法对非静态方法进行静态引用

gcuhipw9  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(570)

这个问题在这里已经有答案了

Java8:方法引用绑定接收器和未绑定接收器之间的差异(6个答案)
三年前关门了。
我阅读教程是为了参考特定类型的任意对象的示例方法。这是链接https://docs.oracle.com/javase/tutorial/java/javaoo/methodreferences.html
所以我写了我自己的代码,但我无法删除错误。 Arrays.sort(arr, String::compareToIgnoreCase); 是法律声明但是 Consumer m2 =Myclass::doit; 给出一个错误。如何解决此错误?引用特定类型的任意对象的示例方法的概念是否适用于类java字符串的内置类?
这是我的密码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

interface Myinter {
 void doit(List<String> s);
}
public class Myclass implements Myinter {
    public static void main(String[] args) {
        List<String> obj = new ArrayList<String>();
        obj.add("raj");
        obj.add("gopal");
        obj.add("bhallamudi");
        String arr[] = new String[obj.size()];
        arr = obj.toArray(arr);
        Arrays.sort(arr, String::compareToIgnoreCase);
        for (String s : arr)
            System.out.println(s + " ");

          Consumer<List<String>> m2 =Myclass::doit;
          m2.accept(obj);
    }
    @Override
    public void doit(List<String> s) {
            System.out.println(s);

    }
}
bqjvbblv

bqjvbblv1#

应用方法引用的规则同样适用于标准java类,比如string和您自己的类。在您的示例中,有两种方法引用的用法。1) 而不是正常的调用 doit 以及2)替换lambda表达式。
java8中的符号 Myclass::doit 意味着您正在调用静态方法 doitMyclass . 相反,您必须为创建一个对象 Myclass 并按如下方式调用对象:

Myclass reallyMyClass = new Myclass();

Consumer<List<String>> m2 = reallyMyClass::doit;
m2.accept(obj);

使用方法引用替换lambda时,表示法略有不同,可以使用类的名称来使用引用。因此,在您的示例中,使用string展开时意味着:

Arrays.sort(arr, (s1, str) -> s1.compareToIgnoreCase(str));

它的简写版本将替换lambda参数的定义并调用 s1 使用参数 str 作为 compareToIgnoreCase 因此:

Arrays.sort(arr, String::compareToIgnoreCase);

为了进一步的参考,这篇博文是关于这个主题的一篇很好的读物:https://www.codementor.io/eh3rrera/using-java-8-method-reference-du10866vx

83qze16e

83qze16e2#

创建对示例方法的未绑定引用时,receiver示例将成为第一个函数参数。
如果是 String::compareToIgnoreCase ,将有两个字符串参数传递给 Comparator.compare ; 方法 compareToIgnoreCase 将在第一次调用时调用,并将第二次作为参数传递。
同样地,你必须使用

BiConsumer<Myclass,List<String>> m2 = Myclass::doit;
m2.accept(new MyClass(), obj);

因为你不能调用示例方法 doit 没有一个 Myclass . 或者,结合您的界面:

BiConsumer<Myinter,List<String>> m2 = Myinter::doit;
m2.accept(new MyClass(), obj);

这里是实现 Myinter 足够了。

相关问题