Java 通过使用try-catch避免无休止的空/空检查

Java 通过使用try-catch避免无休止的空/空检查,java,Java,假设我想访问以下内容 productList.get(0).getCustomerList().get(0).getAddressList().get(0).getRegion.getCode() 在每个级别,我都需要检查空列表或空列表。数据结构非常复杂,重构可能是一种选择,但也可能过于复杂或不可能 由此产生的代码将是: if(productList != null && !productList.isEmpty() && productList

假设我想访问以下内容

productList.get(0).getCustomerList().get(0).getAddressList().get(0).getRegion.getCode()
在每个级别,我都需要检查空列表或空列表。数据结构非常复杂,重构可能是一种选择,但也可能过于复杂或不可能

由此产生的代码将是:

if(productList != null 
   && !productList.isEmpty() 
   && productList.get(0).getCustomerList().get(0) != null 
   && ...){
  return productList.get(0).getCustomerList().get(0).getAddressList(0).getRegion.getCode();
}
生成的代码丑陋、冗长,没有任何真正的业务逻辑,而且很难阅读。有什么聪明的方法可以避免这种情况吗?是否可以接受这样做:

try{
  return productList.get(0).getCustomerList().get(0).getAddressList(0).getRegion.getCode();
} catch(NullPointerException | IndexOutOfBoundException e){
  return null;
}

我只是把它分成如下几部分:

Product p = getElementOrNull( productList, 0 );
if( p == null ) { return null; }

Customer c = getElementOrNull( p.getCustomerList(), 0 );
if( c == null ) { return null; }

Address a = getElementOrNull( c.getAddressList(), 0 );
if( a == null ) { return null; }   

Region r = a.getRegion();
if( r == null ) { return null; }   

return r.getCode();

T getElementNull(列表,int索引){
if(list==null | | index<0 | | index>=list.size()){
返回null;
}      
返回列表。获取(索引);
}
使用异常来处理正常的代码流,就像您通常建议的那样,这是不可取的。您有时会看到它是这样做的,在某些情况下它会工作,但它会使代码更难理解(什么可能是空的,或者哪个索引可能是错误的),并且可能会混淆那些偶然发现您的代码并得出结论认为在其他情况下以这种方式使用异常是可以的开发人员


在您的情况下,您似乎可以将链中的任何元素/列表设置为null,但假设地址必须始终具有区域或客户必须始终具有地址。在这些情况下,您可以假设这些东西不是空的,并调整空检查以抛出一个更具描述性的异常(至少有更好的消息)——这在像您这样的“catch all”catch块中是无法做到的。

下面是使用Java 8 Optional的另一个建议

Predicate<List> hasElement = list -> list != null && !list.isEmpty();

String code = Optional.ofNullable(productList)
.filter(hasElement).map(p -> p.get(0).getCustomerList())
.filter(hasElement).map(c -> c.get(0).getAddressList())
.filter(hasElement).map(a -> a.get(0).getRegion())
.map(Region::getCode)
.orElse(null);
谓词元素=列表->列表!=空&!list.isEmpty();
字符串代码=可选。不可用(productList)
.filter(hasElement).map(p->p.get(0).getCustomerList())
.filter(hasElement).map(c->c.get(0).getAddressList())
.filter(hasElement).map(a->a.get(0.getRegion())
.map(区域::getCode)
.orElse(空);

…一个提示:{product Side note:列表和其他可枚举项无论如何都不应该为空。空,是,空,否。你在使用Java-8吗?
Predicate<List> hasElement = list -> list != null && !list.isEmpty();

String code = Optional.ofNullable(productList)
.filter(hasElement).map(p -> p.get(0).getCustomerList())
.filter(hasElement).map(c -> c.get(0).getAddressList())
.filter(hasElement).map(a -> a.get(0).getRegion())
.map(Region::getCode)
.orElse(null);