Java 8方法对非静态方法的引用

Java 8方法对非静态方法的引用,java,java-8,method-reference,Java,Java 8,Method Reference,为什么这不起作用?我收到编译器错误“无法对非静态方法print进行静态引用…” 我想我现在明白了。流中的内容是String类型的,因此我不能调用String intance上的print 例如,这是有效的 public class Chapter3 { final String value; public Chapter3(String value) { this.value = value; } public void print() { System.out.printl

为什么这不起作用?我收到编译器错误“无法对非静态方法print进行静态引用…”


我想我现在明白了。流中的内容是String类型的,因此我不能调用String intance上的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);
}
}

forEach
接受
使用者无论是使用方法引用、lambda表达式还是普通方法调用,实例方法都需要适当的实例进行调用。该实例可能由函数调用提供,例如,如果
forEach
预期一个
BiConsumer
它起作用。但是,由于在您的案例中,
forEach
需要一个
Consumer
,因此范围中没有第3章的实例。您可以通过将
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);
    }
}

这里是
newchapter3()
的结果,这是
Chapter3
的一个新实例,将被捕获以作为对其
print
方法的方法引用,并且可以构造在该实例上调用该方法的
使用者。

以防您试图从代码运行的同一对象应用实例方法

Arrays.asList("a", "b", "c").forEach(this::print);

如果函数类型与生成函数的对象不匹配,则会看到非静态错误。例如,这一行代码将不会编译,因为该函数期望一个Foo作为其作用的类型,但该函数用于Foobar:

Function<Foo, Bar> func = Foobar::getBar;
函数func=Foobar::getBar;
它不仅处理它在for循环或任何其他参数中的时间,也不必处理“范围内的内容”。这是一个类型不匹配错误,java在使用新函数对象时错误地标记了它。将此与构造其他泛型时发生的情况进行比较:

List<Foo> list = new ArrayList<Bar>();
List List=new ArrayList();
该行代码将无法编译,错误为“不兼容类型”。 更好的是,尽管也以几乎完全相同的方式处理函数对象,但此代码也会因不兼容类型而失败:

public void test() {
    Function<Foo, Double> test2 = Foo::getDouble;
    //fails with Incompatible types
    test3(test2);
}


public void test3(Function<Foobar, Double> function) {
    //who cares
}
公共无效测试(){
函数test2=Foo::getDouble;
//失败,类型不兼容
test3(test2);
}
公共void test3(函数){
//谁在乎
}

我的最佳建议是,当您开始出现此错误时,将函数声明拖到新行,您应该能够看到实际问题是什么。java选择“非静态方法不能从静态上下文引用”的原因我无法理解。

您可以使您的
打印
函数
静态
,这样您就不需要实例来调用它:

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

一句话的回答是:范围内没有第三章的例子……谢谢你消除了我的疑虑。
public class Chapter3 {
    public static void print(String s) {
        System.out.println(s);
    }
    public static void main(String[] args) {
        Arrays.asList("a", "b", "c").forEach(Chapter3::print);
    }
}