使用java8方法引用的Nullcheck方法可能吗?

Nac*_*haz 6 java java-8 method-reference

由于丰富的分析,我们的Java代码混杂了可以为空的对象的方法结果的输出.

看起来像这样

namedObject == null ? "?" : namedObject.getName()
Run Code Online (Sandbox Code Playgroud)

是否可以为此编写静态方法?(例如看起来像这样):

Util.nvl( namedObject, NamedObject::getName, "?" )
Run Code Online (Sandbox Code Playgroud)

什么会= Util.nvl看起来像?我已经尝试了一些搜索谷歌,但没有产生任何结果.

这不起作用:

public static <T> T nvl(T value, Function<T, ?> method, T nullSubstition) {
    return value == null ? nullSubstition : (T) method.apply(value);
}
Run Code Online (Sandbox Code Playgroud)

编译器告诉我:非静态方法getName()不能从静态上下文中引用

JB *_*zet 9

您的签名不正确.您希望您的方法将NamedObject作为第一个参数(因此T是NamedObject),并返回一个String(所以现在T是String).

您需要两个泛型类型参数:

public class Utils {

    public static <O, T> T nvl(O value, Function<O, T> method, T nullSubstition) {
        return value == null ? nullSubstition : method.apply(value);
    }

    static class NamedObject {
        String getName() {
            return "foo";
        }
    }

    public static void main(String[] args) {
        NamedObject foo = null;
        String name = Utils.nvl(foo, NamedObject::getName, "bar");
        System.out.println("name = " + name); // name = bar

        foo = new NamedObject();
        name = Utils.nvl(foo, NamedObject::getName, "bar");
        System.out.println("name = " + name); // name = foo
    }
}
Run Code Online (Sandbox Code Playgroud)

一个更好的签名,允许更多的灵活性,将是

public static <O, T> T nvl(O value, Function<? super O, ? extends T> method, T nullSubstition) {
    return value == null ? nullSubstition : method.apply(value);
}
Run Code Online (Sandbox Code Playgroud)


Mur*_*nik 5

您的方法的泛型未正确定义.您正在尝试创建(接收某种类型的对象的方法T,为了便于讨论,或NamedObject在给定的例子),并应用返回不同类型的对象(一个方法S,为了便于讨论,或String在给定的例子),S如果传递的对象是null:

public static <T, S> S nvl(T value, Function<T, S> method, S nullSubstition) {
    return value == null ? nullSubstition : (S) method.apply(value);
}
Run Code Online (Sandbox Code Playgroud)

请注意,Java 8 Optional可能允许您以更优雅的方式编写它(虽然优雅在旁观者眼中):

public static <T, S> S nvl(T value, Function<T, S> method, S nullSubstition) {
    return Optional.ofNullable(value).map(method).orElse(nullSubstition);
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的例子.也许这个函数的一个好名字是`optionalMapOrElse`,因为它是该表示法的简写. (2认同)