可以说我们有以下课程:
public class NameCreator {
public String createName(String lastname) {
return lastname;
}
public String createName(String lastname, String firstName) {
return lastname + " " + firstname
}
...
}
如果我想通过Java 8方法参考来调用它:
NameCreator::createName
我会收到错误消息:
Cannot resolve method createName
如何定义我要调用的那些方法?
答案 0 :(得分:11)
NameCreator::createName
意味着该方法是静态的(下表中的类型1),或者功能接口目标也采用该类的实例(类型3,例如
{ {1}})。您的方法不是静态的,因此您的目标可能没有实例,这就是为什么您会收到“无法解析方法”错误的原因。您可能想在 instance (类型2)上使用方法引用。在课程中,您可以使用:
BiFunction<NameCreator, String, String>
您可以在课程之外使用
Function<String, String> func = this::createName
关于使用一参数还是两参数版本,取决于目标功能接口。上面将使用您的第一种方法,因为NameCreator creator = new NameCreator();
Function<String, String> func = creator::createName;
接受一个String并返回一个String。以下面的功能接口为例,将使用您的第二种方法:
Function<String, String>
请参阅:Function
,BiFunction
和整个java.util.function
package
您可能还对the Java tutorial on method references感兴趣,尤其是这一部分:
方法参考有四种:
NameCreator creator = new NameCreator();
BiFunction<String, String, String> func = creator::createName;
答案 1 :(得分:4)
方法引用依赖于推断。因此,如果没有适当的上下文来让编译器可以推断目标功能接口,则会引起解析错误。
您应该将其分配给声明与签名匹配的方法的接口类型(或在定义目标类型的上下文中使用它,例如方法参数)。
例如:
interface INameCreator {
String create(String name);
}
interface INamesCreator {
String create(String firstName, String lastName);
}
然后您可以使用方法引用:
//match NameCreator.createName(String)
INameCreator creator = this::createName //within the class
INameCreator creator = nameCreatorInstance::createName
和
//match NameCreator.createName(String, String)
INamesCreator creator = this::createName //within the class
INamesCreator creator = nameCreatorInstance::createName
如果该方法是静态的,则可以在同一上下文中使用NameCreator::createName
语法。
答案 2 :(得分:0)
如果要基于字符串创建NameCreator
类型的实例,请使用以下方法:
public static class NameCreator {
public static String createName(String lastname) {
return lastname;
}
public static String createName(String lastname, String firstName) {
return lastname + " " + firstName;
}
}
然后拨打电话,例如:
List<String> items = new ArrayList<>();
//
items.forEach(NameCreator::createName);//uses the first method
Map<String, String> map = new HashMap<>();
//
map.forEach(NameCreator::createName); //uses the second method