为什么这个方法引用赋值编译?

我很努力地看到为什么下面的代码编译:

public class MethodRefs { public static void main(String[] args) { Function<MethodRefs, String> f; f = MethodRefs::getValueStatic; f = MethodRefs::getValue; } public static String getValueStatic(MethodRefs smt) { return smt.getValue(); } public String getValue() { return "4"; } } 

我可以明白为什么第一个赋值是有效的 – getValueStatic显然匹配指定的Functiontypes(它接受一个MethodRefs对象并返回一个String ),但是第二个让我感到困惑 – getValue方法不接受任何参数,为什么它仍然是有效的把它分配给f

第二个

 f = MethodRefs::getValue; 

是相同的

 f = (MethodRefs m) -> m.getValue(); 

对于非静态方法,在被调用者中总是有一个隐含的参数。

注意:在字节代码级别的实现略有不同,但是它也是一样的。

让肉有点:

 import java.util.function.Function; public class MethodRefs { public static void main(String[] args) { Function<MethodRefs, String> f; final MethodRefs ref = new MethodRefs(); f = MethodRefs::getValueStatic; f.apply(ref); //is equivalent to MethodRefs.getValueStatic(ref); f = MethodRefs::getValue; f.apply(ref); //is now equivalent to ref.getValue(); } public static String getValueStatic(MethodRefs smt) { return smt.getValue(); } public String getValue() { return "4"; } } 

一个非静态的方法本质上把它作为一种特殊的参数。 通常这个参数是用特殊的方式写的(在方法名之前,而不是在它之后的括号内),但是这个概念是相同的。 getValue方法接受一个MethodRefs对象(它的this )并返回一个string,所以它与Function<MethodRefs, String>接口兼容。

在Java教程中解释了有四种不同types的方法引用:

  1. 引用一个静态方法
  2. 引用特定对象的实例方法
  3. 引用特定types任意对象的实例方法
  4. 引用一个构造函数

你的情况是#3,这意味着当你有一个MethodRef实例,即ref ,调用你的函数f将相当于String s = ref.getValue()

对于非静态方法,这种types被认为是第一个参数types。 由于它是MethodRefstypes,所以types检出。