方法参考投射如何工作?

Ksh*_*rma 4 java lambda casting java-8 method-reference

public class Main {
    interface Capitalizer {
        public String capitalize(String name);
    }

    public String toUpperCase() {
        return "ALLCAPS";
    }

    public static void main(String[] args) {
        Capitalizer c = String::toUpperCase; //This works
        c = Main::toUpperCase; //Compile error
    }
}
Run Code Online (Sandbox Code Playgroud)

两者都是具有相同签名的实例方法.为什么一个工作而另一个不工作?

签名String::toUpperCase:String toUpperCase();

小智 6

有3个构造引用方法:

  1. object::instanceMethod
  2. Class::staticMethod
  3. Class::instanceMethod

这条线:

Capitalizer c = String::toUpperCase; //This works
Run Code Online (Sandbox Code Playgroud)

使用3'rd构造 - Class::instanceMethod.在这种情况下,第一个参数成为方法的目标.此构造与以下Lambda等效(翻译):

Capitalizer = (String x) -> x.toUpperCase();
Run Code Online (Sandbox Code Playgroud)

此Lambda表达式有效,因为Lambda 作为参数获取String并返回String结果 - 根据Capitalizer接口的要求.

这条线:

c = Main::toUpperCase; //Compile error
Run Code Online (Sandbox Code Playgroud)

翻译为:

(Main m) ->  m.toUpperCase();
Run Code Online (Sandbox Code Playgroud)

哪个不适用于Capitalizer界面.您可以通过更改Capitalizer为:

interface Capitalizer {
    public String capitalize(Main name);
}
Run Code Online (Sandbox Code Playgroud)

这个改变之后Main::toUpperCase会编译.