我遇到这样一种情况,即我以类似于这个问题的方式返回一个可能会或可能没有完全初始化的对象:
Null coalescing within an invocation chain
我意识到链接的问题是一个C#问题,但它仍与Java相关。
似乎应该可以使用反射在Java中制作类似的东西。常见的模式是使用getter和setter,因此我们希望能够在查找null时重复调用getter。该方法看起来像这样:
public static Object coalesce(Object root, String... methods);
所以,你最终会做这样的事情:
Dog dog = new dog();
dog.setFur(new Fur());
dog.getFur().setColor(new Color());
// And so on
Object.coalesce(dog, "getFur", "getColor", "getRGBValues", "getRed");
结果可能是dog.getFur()。getColor()。getRGBValues()。getRed()的结果,或者如果dog或任何这些方法的结果为null,它将为null。
这样的事情存在吗?我已经在Java API上进行了大量基于正则表达式的搜索,但我什么也没找到。不过,这样的事情存在是有意义的。
编辑:
短版本,看起来像这样的东西不存在开箱即用。很高兴知道。谢谢!
答案 0 :(得分:0)
我认为您可能需要遍历每个提供的方法并检查返回类型:
Method method = <your object>.class.getMethod(<method name>));
if (method.getReturnType() == Void.TYPE) {
// has a void return type
答案 1 :(得分:0)
你可以使这项工作,但它非常难看,而且不是类型安全的。
你真正想要的是像(不是真正的Java)
这样的组合器 static <A,B,C> C comb(Function<A,B> f, Function<B,C> g) {
return new Function<A,C>() {
public C apply(A item) {
B b = f.apply(item);
if (B == null) return null;
return g.apply(b);
};}
然后:
comb(Dog::getFur,
comb(Fur::getColor,
comb(Color::getRGBValues, RGB::getRed))).apply(dog);
也许你可以用Java 8做这样的事情。
答案 2 :(得分:0)
由于我不能发表评论,这必须是一个答案。
我假设您想为许多不同的对象执行此操作,否则您可以使用简单的测试。对于这种横切关注,您可能需要查看AspectJ。它在匹配方法签名和包装/扩展/短路行为方面做得非常好。如果您没有原始源代码,它将特别有用。
答案 3 :(得分:0)
表达式语言(javax.el)可以单独使用。然而,自己做也是可能的。还有一些Bean utils可能会做同样的事情。
public static Object coalesce(Object root, String... methods) {
if (root == null) {
return null;
}
for (String methodName : methods) {
Class<?> klazz = root.getClass();
try {
Method method = klazz.getMethod(methodName);
Object result = method.invoke(root);
root = result;
if (root == null) {
break;
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
// Definitely make a nice informative error message.
}
}
return root;
}
答案 4 :(得分:0)
然后,为什么不简单
Result result = null;
try {
result = obj.getThis().getThat().getAnother(). ... .getLast();
} catch (NullPointerException x) {}