java7:获取可选的嵌套POJO属性
java 7: Get optional nested POJO property
我从 Swift 背景跳回到 Android 我习惯使用这个
的符号
let fooOptional = foo?.fooer?.fooest
print(fooOptional)
在java 8, this is possible:
Optional.of(new Foo())
.map(Foo::Fooer)
.map(Fooer::Fooest)
.ifPresent(System.out::println);
但是,在 java 7 中,如果不求助于更高版本的 Android,就没有真正开箱即用的方法,这不符合我们的最低 SDK 规范。有吗?
如果设置的 pojos 有 getter 调用来获取嵌套属性,您可以使用反射来获取可选的 get 调用并沿着嵌套走下去:
public class NestedOptional<T> {
public static <T> Optional<T> fromNullable(Object obj, String... calls) {
if (obj == null) {
return Optional.absent();
}
for (String call: calls) {
try {
obj = obj.getClass().getMethod(call).invoke(obj);
if (obj == null) {
return Optional.absent();
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException("Couldn't call " + call + "() on " + obj, e);
}
}
return Optional.of(obj);
}
}
如果存在空指针,它将 return Guava 的可选对象在 java 8 之前可用。
有了这个,您就可以:
Optional<Fooest> fooOptional = NestedOptional.fromNullable(foo, "getFooer", "getFooest");
if (fooOptional.isPresent()) {
System.out.println(fooOptional.get().toString());
}
我从 Swift 背景跳回到 Android 我习惯使用这个
的符号let fooOptional = foo?.fooer?.fooest
print(fooOptional)
在java 8, this is possible:
Optional.of(new Foo())
.map(Foo::Fooer)
.map(Fooer::Fooest)
.ifPresent(System.out::println);
但是,在 java 7 中,如果不求助于更高版本的 Android,就没有真正开箱即用的方法,这不符合我们的最低 SDK 规范。有吗?
如果设置的 pojos 有 getter 调用来获取嵌套属性,您可以使用反射来获取可选的 get 调用并沿着嵌套走下去:
public class NestedOptional<T> {
public static <T> Optional<T> fromNullable(Object obj, String... calls) {
if (obj == null) {
return Optional.absent();
}
for (String call: calls) {
try {
obj = obj.getClass().getMethod(call).invoke(obj);
if (obj == null) {
return Optional.absent();
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException("Couldn't call " + call + "() on " + obj, e);
}
}
return Optional.of(obj);
}
}
如果存在空指针,它将 return Guava 的可选对象在 java 8 之前可用。
有了这个,您就可以:
Optional<Fooest> fooOptional = NestedOptional.fromNullable(foo, "getFooer", "getFooest");
if (fooOptional.isPresent()) {
System.out.println(fooOptional.get().toString());
}