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>
forEach接受一个Consumer<? super T>(它的签名是default void forEach(Consumer<? super T> action)),这是一个带有accept(T t)单个参数的方法的功能接口.
传递具有参数的方法的非静态方法引用时,实际上有两个参数 - this对Chapter3实例的引用和String参数.这与forEach预期不符.
以防万一,如果您尝试从运行代码的同一对象中应用实例方法
Arrays.asList("a", "b", "c").forEach(this::print);
Run Code Online (Sandbox Code Playgroud)
我想我现在明白了。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)