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
}
}
两者都是具有相同签名的实例方法。为什么一个工作而另一个不工作?
String::toUpperCase
的签名:String toUpperCase();
答案 0 :(得分:6)
引用方法有3种结构:
object::instanceMethod
Class::staticMethod
Class::instanceMethod
该行:
Capitalizer c = String::toUpperCase; //This works
使用3'rd构造 - Class::instanceMethod
。在这种情况下,第一个参数成为方法的目标。此构造与以下Lambda等效(翻译):
Capitalizer = (String x) -> x.toUpperCase();
此Lambda表达式有效,因为Lambda 获取String
作为参数并返回String
结果 - 根据Capitalizer
接口的要求。
该行:
c = Main::toUpperCase; //Compile error
转换为:
(Main m) -> m.toUpperCase();
哪个不适用于Capitalizer
界面。您可以通过将Capitalizer
更改为:
interface Capitalizer {
public String capitalize(Main name);
}
此更改后Main::toUpperCase
将编译。
答案 1 :(得分:4)
你有一个方法
public String capitalize(String name);
取String
并返回String
。这种方法可以有多种模式。
构造函数
c = String::new; // calls new String(String)
// or
c = s -> new String(s);
String
上的一个不带参数的函数
c = String::toLowerCase; // instance method String::toLowerCase()
// or
c = s -> s.toLowerCase();
将String作为唯一参数的方法的
// method which takes a String, but not a Main
public static String toUpperCase(String str) {
c = Main::toUpperCase;
// or
c = s -> toUpperCase(s);
在每种情况下,引用的方法都必须使用String。
如果不是,你可以这样做。
c = s -> capitalize(); // assuming Main.capitalize() is static
这告诉编译器忽略输入。
答案 2 :(得分:0)
你应该改变:
Dx
到
public String toUpperCase()
您应该阅读method references上的java教程。不同类型的方法引用,并且有public static String toUpperCase(String text)
的类似示例(引用特定类型的任意对象的实例方法)。
方法引用String :: compareToIgnoreCase的等效lambda表达式将具有形式参数列表(String a,String b),其中a和b是用于更好地描述此示例的任意名称。方法引用将调用方法a.compareToIgnoreCase(b)。