为什么这个方法引用赋值编译?
我很努力地看到为什么下面的代码编译:
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
显然匹配指定的Function
types(它接受一个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的方法引用:
- 引用一个静态方法
- 引用特定对象的实例方法
- 引用特定types任意对象的实例方法
- 引用一个构造函数
你的情况是#3,这意味着当你有一个MethodRef
实例,即ref
,调用你的函数f
将相当于String s = ref.getValue()
。
对于非静态方法,这种types被认为是第一个参数types。 由于它是MethodRefs
types,所以types检出。