Java 8方法引用特定类型的任意对象的实例方法

时间:2015-08-27 16:09:35

标签: java functional-programming java-8

为什么以下不起作用?

import java.util.function.Function;

public class MethodRefTest {
   public String passMeAround( String input ) {
      return input + " been passed to me";
   }

   public Function<String, String> testReferences() {
      final Function<String, String> f1 = MethodRefTest::passMeAround;
      return f1;
   }

   public static void main( String[] args ) {
      new MethodRefTest()
            .testReferences()
            .apply( "foo" );
   }
}

Javac告诉我:

MethodRefTest.java:14: error: invalid method reference
      final Function<String, String> f1 = MethodRefTest::passMeAround;
                                          ^
  non-static method passMeAround(String) cannot be referenced from a static context
1 error

我不明白为什么上下文是静态的。我读过this但似乎没有回答手头的问题。

修改

同样根据oracle,可以通过ContainingType::methodName

“引用特定类型的任意对象的实例方法

编辑2

@ marko-topolnik帮我理解了我的错误。 Function<String, String> f1 = MethodRefTest::passMeAround; 指静态方法String MethodRefTest.passMeAround(String)

BiFunction<MethodRefTest, String, String> f1 = MethodRefTest::passMeAround;
另一方面,

指的是any instance的实例方法,它在apply子句中传递。

BiFunction<MethodRefTest, String, String> f2 = MethodRefTest::passMeAround;
//call instance method
f2.apply(new MethodRefTest(), "some string");

3 个答案:

答案 0 :(得分:15)

因为您将其称为

MethodRefTest::passMeAround

您应该将其称为

this::passMeAround

提供用于上下文的实例。

查看当前代码的另一种方法是说MethodRefTest::passMeAroundBiFunction<MethodRefTest, String, String>,并且此lambda形状与目标网站不匹配。所以,或者,你可能已经写过了

public BiFunction<MethodRefTest, String, String> testReferences() {
  return MethodRefTest::passMeAround;
}

并在主要方法中

final MethodRefTest t = new MethodRefTest();
t.testReferences().apply( t, "foo" );

你读过的材料可能不够有用,所以让我展开。与

this::passMeAround

你得到一个lambda对象,该对象从创建它的上下文捕获 {/ 1}}实例,但是

this

你得到一个“纯粹的”非捕获lambda,它代表某些实例上指定方法的调用,带有一些字符串参数,所以当你{{ 1}}它,你需要传递它们。

答案 1 :(得分:0)

passMeAround更改为静态:

 public static String passMeAround( String input ) {
      return input + " been passed to me";
   }

或者将其称为实例方法:

 public Function<String, String> testReferences() {
      final Function<String, String> f1 = this::passMeAround;
      return f1;
 } 

答案 2 :(得分:-1)

要回答关于上下文为何是静态的问题,那是因为::之前的部分是类的名称而不是实例的名称。如果您没有实例,则只能访问静态成员。