如何在java中摆脱过多的空值检查?

时间:2013-02-22 09:39:41

标签: java design-patterns

假设我有一些这样的代码:

Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);

如果找不到Vehicle,则此方法将返回null。规范说在这种情况下我必须抛出MyObjectNotFoundException所以代码变成这样:

Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);
MyObjectNotFoundException.throwIfNull(vehicle, Vehicle.class, vehicleId);

如果我想摆脱对throwIfNull的调用,我该怎么办?无论如何,它并不是真正的DRY和糟糕的设计选择。必须有一些我不知道的设计模式。我在网上搜索过,但没有找到真正有用的东西。

一个简单的解决方案可能是将代码放入我的存储库,但我使用SpringData,因此它只是一个接口:

public interface VehicleRepository extends Repository<Vehicle, Long>

// ...

@Query("select v from Vehicle v LEFT JOIN FETCH v.technicalData td LEFT JOIN FETCH v.registrationData rd"
    + " where v.vehicleId = ?")
Vehicle findByIdInitialized(Long vehicleId);

7 个答案:

答案 0 :(得分:3)

听起来基本上你希望你的存储库支持这个:

Vehicle vehicle = vehicleRepository.loadExisting(vehicleId);

loadExistingfindByIdInitialized之间的区别在于前期望实体存在,如果不存在则会抛出异常。

这样,所有存储库客户端都可以决定是否在执行查找时,他们是否希望缺少实体来导致异常。您甚至可能会发现ID中的所有查找都会引发异常 - 在这种情况下,您可以返回使用单个方法。

编辑:如果存储库是自动生成的,我将采用以下三种方法之一:

  • 包裹它
  • 延伸
  • 修改生成器

哪种选择最合适取决于具体细节。

答案 1 :(得分:0)

您可以在Java中查看@NotNull注释。它有几种风格,其中一些在编译时进行验证,其中一些在运行时进行。某些编辑器(如IntelliJ IDEA)可以在您进行可能导致NPE的操作时发出警告。

Which @NotNull Java annotation should I use? Avoiding != null statements http://docs.oracle.com/javaee/6/api/javax/validation/constraints/NotNull.html

答案 2 :(得分:0)

如果您可以重新设计存储库本身以抛出所需的异常,那当然是最好的。如果没有这个,你需要修补行为的解决方法。

一种方法是反射:在一个接收repository作为字符串并以反射方式调用它的方法中调用findByIdInitialized。然后该方法可以抛出适当的异常。

另一种方法可能是让一些AOP做同样的事情,但也许更安全。

答案 3 :(得分:0)

我建议你为findByIdInitialized添加一个可以为null的参数,它就像:

Vehicle findByIdInitialized(int vehicleId, boolean throwException) {
   // implementation behavior...

   if (throwException) {
       MyObjectNotFoundException.throwIfNull(vehicle, Vehicle.class, vehicleId);
   }
}

答案 4 :(得分:0)

使用此:

import static java.util.Objects.requireNonNull;

.
.
.

Object o = requireNonNull(obj);

答案 5 :(得分:0)

听起来像你想要&#34;方法返回&#34; AOP建议,拦截空值并抛出异常。

答案 6 :(得分:-2)

您可以使用NullObject设计模式,但抛出异常IMHO是最佳选择。

要保持DRY,你应该把它扔进findbyIdInitialized