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

时间:2017-04-20 15:04:54

标签: java java-8

我很难理解为什么以下代码会编译:

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类型匹配(它接受MethodRefs对象并返回String),但是第二个让我感到困惑 - getValue方法不接受任何参数,那么为什么将它分配给f仍然有效?

5 个答案:

答案 0 :(得分:50)

第二个

f = MethodRefs::getValue;

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

对于非静态方法,总是有一个隐式参数,在被调用者中表示为this

注意:字节代码级别的实现略有不同,但它的功能相同。

答案 1 :(得分:9)

非静态方法本质上将其this引用作为一种特殊的参数。通常,该参数是以特殊方式编写的(在方法名称之前,而不是在其后的括号内),但概念是相同的。 getValue方法使用MethodRefs对象(其this)并返回一个字符串,因此它与Function<MethodRefs, String>接口兼容。

答案 2 :(得分:9)

让我们充实一点:

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";
  }
}

答案 3 :(得分:6)

在Java教程中,解释了有4种不同类型的方法引用:

  1. 对静态方法的引用
  2. 引用特定对象的实例方法
  3. reference to an instance method of an arbitrary object of a particular type
  4. 对构造函数的引用
  5. 您的案例是#3,这意味着如果您有MethodRef的实例,即ref,则在您的函数apply上调用f将等同于{{1 }}

答案 4 :(得分:5)

对于非静态方法,ggplot的类型被隐式地视为第一个参数类型。由于它是this类型,因此检查类型。