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()不能从静态上下文中引用
您的签名不正确.您希望您的方法将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)
您的方法的泛型未正确定义.您正在尝试创建(接收某种类型的对象的方法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)