方法引用转换如何工作?
How does method reference casting work?
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();
你应该改变:
public String toUpperCase()
到
public static String toUpperCase(String text)
您应该阅读 method references 上的 java 教程。不同类型的方法引用,并且有一个类似的示例 String::compareToIgnoreCase
(对特定类型的任意对象的实例方法的引用)。
The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b).
你有一个方法
public String capitalize(String name);
需要一个 String
和 returns 一个 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();
以字符串作为唯一参数的方法
// method which takes a String, but not a Main
public static String toUpperCase(String str) {
c = Main::toUpperCase;
// or
c = s -> toUpperCase(s);
在任何情况下,引用的方法都必须采用字符串。
如果没有,您可以改为执行此操作。
c = s -> capitalize(); // assuming Main.capitalize() is static
这告诉编译器忽略输入。
有 3 个结构可以引用一个方法:
object::instanceMethod
Class::staticMethod
Class::instanceMethod
行:
Capitalizer c = String::toUpperCase; //This works
使用第 3 个构造 - Class::instanceMethod
。在这种情况下,第一个参数成为方法 的目标。此构造等效于(翻译)以下 Lambda:
Capitalizer = (String x) -> x.toUpperCase();
此 Lambda 表达式有效,因为 Lambda 获取 String
作为参数和 returns String
结果 - 根据 Capitalizer
接口的要求.
行:
c = Main::toUpperCase; //Compile error
转换为:
(Main m) -> m.toUpperCase();
不适用于 Capitalizer
界面。您可以通过将 Capitalizer
更改为:
来验证这一点
interface Capitalizer {
public String capitalize(Main name);
}
此更改后 Main::toUpperCase
将编译。
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();
你应该改变:
public String toUpperCase()
到
public static String toUpperCase(String text)
您应该阅读 method references 上的 java 教程。不同类型的方法引用,并且有一个类似的示例 String::compareToIgnoreCase
(对特定类型的任意对象的实例方法的引用)。
The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b).
你有一个方法
public String capitalize(String name);
需要一个 String
和 returns 一个 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();
以字符串作为唯一参数的方法
// method which takes a String, but not a Main
public static String toUpperCase(String str) {
c = Main::toUpperCase;
// or
c = s -> toUpperCase(s);
在任何情况下,引用的方法都必须采用字符串。
如果没有,您可以改为执行此操作。
c = s -> capitalize(); // assuming Main.capitalize() is static
这告诉编译器忽略输入。
有 3 个结构可以引用一个方法:
object::instanceMethod
Class::staticMethod
Class::instanceMethod
行:
Capitalizer c = String::toUpperCase; //This works
使用第 3 个构造 - Class::instanceMethod
。在这种情况下,第一个参数成为方法 的目标。此构造等效于(翻译)以下 Lambda:
Capitalizer = (String x) -> x.toUpperCase();
此 Lambda 表达式有效,因为 Lambda 获取 String
作为参数和 returns String
结果 - 根据 Capitalizer
接口的要求.
行:
c = Main::toUpperCase; //Compile error
转换为:
(Main m) -> m.toUpperCase();
不适用于 Capitalizer
界面。您可以通过将 Capitalizer
更改为:
interface Capitalizer {
public String capitalize(Main name);
}
此更改后 Main::toUpperCase
将编译。