lla*_*all 34 java null class ternary
想象一下,我有一个班级家庭.它包含一个人员列表.每个(类)Person包含一个(类)地址.每个(类)地址包含一个(类)PostalCode.任何"中间"类都可以为null.
那么,有没有一种简单的方法来获取PostalCode,而不必在每一步检查null?即,有没有办法避免以下菊花链代码?我知道没有"原生"Java解决方案,但希望有人知道库或其他东西.(已检查Commons&Guava并没有看到任何内容)
if(family != null) {
if(family.getPeople() != null) {
if(family.people.get(0) != null) {
if(people.get(0).getAddress() != null) {
if(people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
不,不能改变结构.它来自我无法控制的服务.
不,我不能使用Groovy,它是方便的"猫王"操作员.
不,我宁愿不等待Java 8:D
我不敢相信我是第一个生病的人,厌倦了写这样的代码,但我找不到解决办法.
想法?
谢谢
-
llappall
小智 18
您可以用于:
product.getLatestVersion().getProductData().getTradeItem().getInformationProviderOfTradeItem().getGln();
Run Code Online (Sandbox Code Playgroud)
可选等效项:
Optional.ofNullable(product).map(
Product::getLatestVersion
).map(
ProductVersion::getProductData
).map(
ProductData::getTradeItem
).map(
TradeItemType::getInformationProviderOfTradeItem
).map(
PartyInRoleType::getGln
).orElse(null);
Run Code Online (Sandbox Code Playgroud)
ami*_*mit 14
您的代码行为与...相同
if(family != null &&
family.getPeople() != null &&
family.people.get(0) != null &&
family.people.get(0).getAddress() != null &&
family.people.get(0).getAddress().getPostalCode() != null) {
//My Code
}
Run Code Online (Sandbox Code Playgroud)
由于短路评估,这也是安全的,因为如果第一个是假的,第二个条件将不会被评估,如果第二个是假的,第三个条件将不会被评估,......并且你将不会获得NPE,因为如果它.
Ami*_*pta 10
如果您使用的是 java8,那么您可以使用;
resolve(() -> people.get(0).getAddress().getPostalCode());
.ifPresent(System.out::println);
:
public static <T> Optional<T> resolve(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e) {
return Optional.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
参考:避免空检查
你可以得到的最接近的是利用条件中的捷径规则:
if(family != null && family.getPeople() != null && family.people.get(0) != null && family.people.get(0).getAddress() != null && family.people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,捕捉异常而不是提前测试条件是一个可怕的想法.
小智 5
您可以通过利用 Java 8 可选类型来摆脱所有这些 null 检查。
流方法 - map()接受 Function 类型的 lambda 表达式,并自动将每个函数结果包装到Optional 中。这使我们能够连续传输多个映射操作。空检查会在底层自动处理。
Optional.of(new Outer())
.map(Outer::getNested)
.map(Nested::getInner)
.map(Inner::getFoo)
.ifPresent(System.out::println);
Run Code Online (Sandbox Code Playgroud)
我们还有另一种选择来实现相同的行为,即利用供应商函数来解析嵌套路径:
public static <T> Optional<T> resolve(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e) {
return Optional.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
如何调用新方法?往下看:
Outer obj = new Outer();
obj.setNested(new Nested());
obj.getNested().setInner(new Inner());
resolve(() -> obj.getNested().getInner().getFoo())
.ifPresent(System.out::println);
Run Code Online (Sandbox Code Playgroud)
这不是一个很酷的想法,但是捕获异常怎么样:
try
{
PostalCode pc = people.get(0).getAddress().getPostalCode();
}
catch(NullPointerException ex)
{
System.out.println("Gotcha");
}
Run Code Online (Sandbox Code Playgroud)