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
}
}
Both are instance methods with same signature. Why does one work and the other doesn't?
两者都是具有相同签名的实例方法。为什么一个工作而另一个不工作?
Signature of String::toUpperCase
: String toUpperCase();
String :: toUpperCase的签名:String toUpperCase();
3 个解决方案
#1
There are 3 constructs to reference a method:
有3个构造引用方法:
object::instanceMethod
-
Class::staticMethod
Class::instanceMethod
The line:
Capitalizer c = String::toUpperCase; //This works
use 3'rd construct - Class::instanceMethod
. In this case first parameter becomes the target of the method. This construct is equivalent (translates) to following Lambda:
使用3'rd构造 - Class :: instanceMethod。在这种情况下,第一个参数成为方法的目标。此构造与以下Lambda等效(翻译):
Capitalizer = (String x) -> x.toUpperCase();
This Lambda expression works because Lambda gets String
as parameter and returns String
result - as required by Capitalizer
interface.
此Lambda表达式起作用,因为Lambda将String作为参数并返回String结果 - 根据Capitalizer接口的要求。
The line:
c = Main::toUpperCase; //Compile error
Translates to:
(Main m) -> m.toUpperCase();
Which does not work with the Capitalizer
interface. You could verify this by changing Capitalizer
to:
哪个不适用于Capitalizer界面。您可以通过将Capitalizer更改为:
interface Capitalizer {
public String capitalize(Main name);
}
After this change Main::toUpperCase
will compile.
在此更改后,Main :: toUpperCase将进行编译。
#2
You have a method which
你有一个方法
public String capitalize(String name);
Takes a String
and returns a String
. Such a method can have a number of patterns.
获取String并返回String。这种方法可以具有许多模式。
A constructor
c = String::new; // calls new String(String)
// or
c = s -> new String(s);
A function on String
which takes no arguments
String上的函数,不带参数
c = String::toLowerCase; // instance method String::toLowerCase()
// or
c = s -> s.toLowerCase();
of a method which takes a String as the only argument
将String作为唯一参数的方法
// method which takes a String, but not a Main
public static String toUpperCase(String str) {
c = Main::toUpperCase;
// or
c = s -> toUpperCase(s);
In every case, the method referenced has to take the String.
在每种情况下,引用的方法都必须采用String。
If not you can do this instead.
如果不是,你可以这样做。
c = s -> capitalize(); // assuming Main.capitalize() is static
This tells the compiler to ignore the input.
这告诉编译器忽略输入。
#3
You should change:
你应该改变:
public String toUpperCase()
to
public static String toUpperCase(String text)
You should read the java tutorial on method references. The different kind of method references and there is a similar example with String::compareToIgnoreCase
(Reference to an Instance Method of an Arbitrary Object of a Particular Type).
您应该阅读有关方法引用的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).
方法引用String :: compareToIgnoreCase的等效lambda表达式将具有形式参数列表(String a,String b),其中a和b是用于更好地描述此示例的任意名称。方法引用将调用方法a.compareToIgnoreCase(b)。
#1
There are 3 constructs to reference a method:
有3个构造引用方法:
object::instanceMethod
-
Class::staticMethod
Class::instanceMethod
The line:
Capitalizer c = String::toUpperCase; //This works
use 3'rd construct - Class::instanceMethod
. In this case first parameter becomes the target of the method. This construct is equivalent (translates) to following Lambda:
使用3'rd构造 - Class :: instanceMethod。在这种情况下,第一个参数成为方法的目标。此构造与以下Lambda等效(翻译):
Capitalizer = (String x) -> x.toUpperCase();
This Lambda expression works because Lambda gets String
as parameter and returns String
result - as required by Capitalizer
interface.
此Lambda表达式起作用,因为Lambda将String作为参数并返回String结果 - 根据Capitalizer接口的要求。
The line:
c = Main::toUpperCase; //Compile error
Translates to:
(Main m) -> m.toUpperCase();
Which does not work with the Capitalizer
interface. You could verify this by changing Capitalizer
to:
哪个不适用于Capitalizer界面。您可以通过将Capitalizer更改为:
interface Capitalizer {
public String capitalize(Main name);
}
After this change Main::toUpperCase
will compile.
在此更改后,Main :: toUpperCase将进行编译。
#2
You have a method which
你有一个方法
public String capitalize(String name);
Takes a String
and returns a String
. Such a method can have a number of patterns.
获取String并返回String。这种方法可以具有许多模式。
A constructor
c = String::new; // calls new String(String)
// or
c = s -> new String(s);
A function on String
which takes no arguments
String上的函数,不带参数
c = String::toLowerCase; // instance method String::toLowerCase()
// or
c = s -> s.toLowerCase();
of a method which takes a String as the only argument
将String作为唯一参数的方法
// method which takes a String, but not a Main
public static String toUpperCase(String str) {
c = Main::toUpperCase;
// or
c = s -> toUpperCase(s);
In every case, the method referenced has to take the String.
在每种情况下,引用的方法都必须采用String。
If not you can do this instead.
如果不是,你可以这样做。
c = s -> capitalize(); // assuming Main.capitalize() is static
This tells the compiler to ignore the input.
这告诉编译器忽略输入。
#3
You should change:
你应该改变:
public String toUpperCase()
to
public static String toUpperCase(String text)
You should read the java tutorial on method references. The different kind of method references and there is a similar example with String::compareToIgnoreCase
(Reference to an Instance Method of an Arbitrary Object of a Particular Type).
您应该阅读有关方法引用的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).
方法引用String :: compareToIgnoreCase的等效lambda表达式将具有形式参数列表(String a,String b),其中a和b是用于更好地描述此示例的任意名称。方法引用将调用方法a.compareToIgnoreCase(b)。