您所在的位置:主页 > JAVA技术 >

避免Java中的空对象检查

时间:2014-08-14 11:57来源:未知 作者:疯狂java 点击:


  Java开发人员最可怕的噩梦应该就是空对象引用的检查了。我敢肯定你一定会经常看到这样的代码:

  public void addAddressToCustomer(Customer customer, Address newAddress){

  if ( cutomer == null || newAddress == null)

  return;

  if ( customer.getAddresses() == null ){

  customer.setAddresses ( new ArrayList<>());

  }

  customer.addAddress(newAddress);

  }

  个人而言,我不太喜欢写这种null检测的代码。本文我将列出一些对我而言比较实用的技巧,这些都是我个人在生产环境及系统中积累的一些经验。

  不要在所有层中都进行null对象的检查。把这类检查限制在偏上层的分层中,比如说UI层,表现层或者API的控制器层。也就是说你需要确保不会有空对象从上层传递到业务逻辑层中。比如你在使用Spring注解来开发一个标准的WEB应用,那么很有可能有一些类是使用@Repository , @Service , @Controller来进行注解的。控制器会负责接受客户端的数据并且传递到@Service类中进行处理。他们应该去确保没有null对象会被传递到服务层中。服务层及下层中的类可以不是null安全的。如果调用它们时传递了null对象,则会抛出NPE异常来警告开发人员,他们得去解决这个问题。记住,NPE并不是用户的错误,而是开发人员的错误,这是应当始终避免的。从HTML表单或者其它用户接口传进来的用户输入也是如此。

  如果遵循上述的方法你就不用再去写那些检查对象是否为null的业务代码了。null对象不应该决定你系统的行为。它们是异常值,应当被当成错误来进行处理,而不是一个有效的业务逻辑状态。

  当从方法中返回列表时,应当始终返回一个空列表而不是null。这样客户端可以无需检查null对象就能够直接遍历列表。遍历空列表是完全可以接受的,它只是什么也没做而已,而遍历null列表则会抛出NPE。

  在持久层中,你可能要搜索某个特定的对象但却没有查找到,常见的情况是返回一个null对象。好吧,这样所有的客户端都得手动检查是否为null了。这种情况下你有两种选择。一个是抛出运行时异常,或者返回一个空的Object。这两种方法我都用过,我建议是根据整体的系统架构以及所使用的工具或者框架来决定。

  当比较字符串时,始终应当把最不可能为空的字符串放到前面,因此,不要这么写:

  customer.getAddress().getStreet().equals("Times Square”)

  而是应该:

  "Times Square".equals(customer.getAddress().getStreet())

  如果你打算或者正在使用Java 8的话,新的Optional类正是你的菜。可以看下这篇文章,里面详细介绍了Optional类的使用。

  下次如果你再要写null检查的代码的时候,先想想看有没有必要这么做。