简体   繁体   中英

How can I get rid of excessive null checking in java?

Suppose I have some code like this:

Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);

If the Vehicle cannot be found this method will return null . The specification says in this case I must throw a MyObjectNotFoundException so the code becomes something like this:

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

What can I do if I want to get rid of calls to throwIfNull . It is not really DRY and a poor design choice anyway. There must be some design pattern unbeknownst to me. I searched on the web but it did not turn up anything really usable.

A straightforward solution might be putting the code into my Repository but I use SpringData for this so it is just an interface:

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);

It sounds like basically you want your repository to support this:

Vehicle vehicle = vehicleRepository.loadExisting(vehicleId);

where the difference between loadExisting and findByIdInitialized would be that the former expects the entity to be present and will throw an a exception if it's not.

That way all repository clients can make a decision as to whether when they perform a lookup, they want the lack of an entity to result in an exception or not. You may even find that all lookups by ID should throw an exception - in which case you can go back to having a single method.

EDIT: If the repository is autogenerated, I'd take one of three approaches:

  • Wrap it
  • Extend it
  • Modify the generator

Which of these choices would be most appropriate would depend on the exact details.

You could look into @NotNull annotations in Java. There are several flavours of it, some of them which do their validation compile-time and some of them at runtime. Some editors (like IntelliJ IDEA) can warn you when you're doing an operation which could result in an NPE.

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

It would of course be best if you could redesign the repository itself to throw the exception you need. Without that, you need workarounds that patch the behavior.

One approach would be reflection: wrap calls to repository in a method that receives findByIdInitialized as a string and calls it reflectively. The method can then throw the appropriate exception.

Another way could be to involve some AOP to do the same thing, but perhaps with more type safety.

I suggest that you add a nullable parameter to findByIdInitialized, and it will be like:

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

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

Use this:

import static java.util.Objects.requireNonNull;

.
.
.

Object o = requireNonNull(obj);

听起来你想“在方法返回后”AOP建议,拦截空值并抛出异常。

You can use NullObject dessign pattern, but thwroing an exception IMHO is the best choice.

To keep in DRY, you should put that throw in findbyIdInitialized .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM