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

时间:2016-12-25 14:55:08

标签: java java-8 method-reference

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

看起来像这样

namedObject == null ? "?" : namedObject.getName()

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

Util.nvl( namedObject, NamedObject::getName, "?" )

什么会= Util.nvl看起来像?我对搜索过的谷歌进行了一些实验,但没有结果。

这不起作用:

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

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

2 个答案:

答案 0 :(得分: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
    }
}

更好的签名,允许更多的灵活性,

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

答案 1 :(得分:5)

您的方法的泛型没有正确定义。您尝试创建一个接收特定类型对象的方法(T,为了参数,或者在给定示例中为NamedObject),并应用方法返回一个不同类型的对象(S,为了参数,或者在给定的例子中为String),如果传递的对象为{,则返回默认的S值{1}}:

null

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

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