使用功能接口在签名上不同的重用方法引用

时间:2016-09-13 15:39:34

标签: java lambda java-8

我有以下方法,它根据语言的存在返回一个字符串。

private String getInLanguage(Function<Locale, String> withLang,
                             Supplier<String> withoutLang) {
    Locale locale = getLocaleFromSomewhere();
    if (locale != null) {
        return withLang.apply(locale);
    } else {
        return withoutLang.get();
    }
}

然后我这样称呼它:

private String getMyObjectName(MyObject obj) {
    return getInLanguage(obj::getName, obj::getName);
}

private String getExternalObjectDescription(ExternalObject obj) {
    return getInLanguage(obj::getDescription, obj::getDescription);
}

其中MyObject包含方法String getName()String getName(Locale loc)

代码中的方法引用对于两个参数看起来都相同。因此,对于纯粹的美学原因,如果可以写的话会很好

return getInLanguage(obj::getName);

可以这样做吗?

3 个答案:

答案 0 :(得分:2)

方法String getName()String getName(Locale loc)是不同的方法,而且它们具有相同名称的事实与它们的工作方式无关,并且无法以任何方式利用它。

通过赋予它们相同的名称,您只记录语义关系。因此,如果要避免指定对同一语义操作的方法引用,则必须在语义级别上解决它。无参数getName方法很可能执行与回退相同的操作,这可以首先提供给其他getName方法:

private String getInLanguage(Function<Locale, String> withLang,
                             Supplier<Locale> defaultSupplier) {
    Locale locale=getLocaleFromSomewhere();
    return withLang.apply(locale == null? defaultSupplier.get(): locale);
}

回退使用默认语言环境:

private String getString1(MyObject obj) {
    return getInLanguage(obj::getName, Locale::getDefault);
}

回退以表示对区域设置不敏感的操作:

private String getString1(MyObject obj) {
    return getInLanguage(obj::getName, ()->Locale.ROOT);
}

答案 1 :(得分:2)

我认为更简洁的解决方案是在一种方法中实现它。使用Optional执行方法引用并避免传递功能接口的混乱语法。

private String getString1(MyObject obj) {
    return Optional.ofNullable(getLocaleFromSomewhere())
        .map(obj::getName)
        .orElseGet(obj::getName);
}

答案 2 :(得分:1)

你陈述The method reference in the code is the same for both arguments,但事实并非如此。 他们指出了不同的方法。所以对你没有好的解决方案。