Java 8方法参考非静态方法

and*_*ana 14 java java-8 method-reference

为什么这不起作用?我得到编译错误"无法对非静态方法打印静态引用..."

public class Chapter3 {
    public void print(String s) {
        System.out.println(s);
    }
    public static void main(String[] args) {
        Arrays.asList("a", "b", "c").forEach(Chapter3::print);
    }
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 18

无论您是使用方法引用,lambda表达式还是普通方法调用,实例方法都需要适当的实例来进行调用.该实例可以由函数调用提供,例如,如果forEach预期BiConsumer<Chapter3,String>它可以工作.但是因为在你的情况下forEach需要a Consumer<String>,所以没有Chapter3范围的实例.您可以通过容易地解决这个问题,改变Chapter3.print到一个static方法,或者通过提供一个实例作为目标的方法调用:

public class Chapter3 {
    public void print(String s) {
        System.out.println(s);
    }
    public static void main(String[] args) {
        Arrays.asList("a", "b", "c").forEach(new Chapter3()::print);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里,将为其方法的方法引用捕获new Chapter3()新实例的结果,并且可以构造对该实例的调用方法.Chapter3printConsumer<String>


Era*_*ran 8

forEach接受一个Consumer<? super T>(它的签名是default void forEach(Consumer<? super T> action)),这是一个带有accept(T t)单个参数的方法的功能接口.

传递具有参数的方法的非静态方法引用时,实际上有两个参数 - thisChapter3实例的引用和String参数.这与forEach预期不符.


Ser*_*kov 6

以防万一,如果您尝试从运行代码的同一对象中应用实例方法

Arrays.asList("a", "b", "c").forEach(this::print);
Run Code Online (Sandbox Code Playgroud)


and*_*ana 5

我想我现在明白了。Stream 中的内容是 String 类型,因此我无法在 String 实例上调用 print...

例如这有效

public class Chapter3 {
final String value;

public Chapter3(String value) {
    this.value = value;
}

public void print() {
    System.out.println(value);
}

public static void main(String[] args) {
    Arrays.asList(new Chapter3("a"), new Chapter3("b")).forEach(Chapter3::print);
}
}
Run Code Online (Sandbox Code Playgroud)