Java 8方法参考:如何确定采用哪种方法?

时间:2018-07-13 10:08:36

标签: java java-8

可以说我们有以下课程:

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

如何定义我要调用的那些方法?

3 个答案:

答案 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>

请参阅:FunctionBiFunction和整个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