Check if in Java

Imagine that I have, say, an XML-created object in Java that contains some of the data that I need. For instance:

<Car> <Engine> <Power> 175 </Power> </Engine> </Car> 

So, if I need engine power, I, followed by the best business software development practices, will do the following:

 Car car = dao.getCar() Power power = car != null && car.engine != null ? power : null return power 

I hate this. Sometimes it seems like half the code is just null checks.

Any ideas?

+5
source share
5 answers

Take a look at Java 8 Optional Class . He does just that: he avoids the ugly null checks.

In your case, you can use this piece of code to avoid them:

 Car car = dao.getCar(); Optional<Car> optionalCar = Optional.ofNullable(car); Optional<Power> optionalPower = getPowerIfPresent(optionalCar); Power power = Optional.empty(); if(optionalPower.isPresent()) { power = optionalPower.get(); } 

after writing a function that returns the power given car :

 public static Optional<Power> getPowerIfPresent(Optional<Car> car) { return car .flatMap(c -> c.getEngine()) .map(e -> e.getPower()); } 
+7
source

This is the same as using Optional , but may be more readable:

 public class NullSafe<T> { private final T value; public NullSafe(@Nullable T value) {this.value = value;} public static <T> NullSafe<T> of(@Nullable T value) {return new NullSafe<>(value);} public <R> NullSafe<R> get(Function<T,R> f) { R newValue = (value != null) ? f.apply(value) : null; return new NullSafe<>(newValue); } public T nullable() { return value; } public T orDefault(T defaultValue) { return (value != null) ? value : defaultValue;} } 

And use:

 Power power = NullSafe.of(dao.getCar()) .get(Car::getEngine) .get(Engine::getPower) .nullable(); // .orDefault(Power.defaultPower()); 
+2
source

Or perhaps create some kind of utility method:

 static <T> Optional<T> tryGet(Supplier<T> getter) { try { return Optional.ofNullable(getter.get()); } catch(NullPointerException ignored) { return Optional.empty(); } } 

Then you can use it as follows:

 System.out.println(tryGet(() -> car.engine.power).orElse(new Power())); 

There is a no-exception library that does this, but you cannot specify it only for silent NPEs.

 Exceptions.silence().get(() -> car.engine.power).orElse(new Power()) 
+1
source

There is another option that you can use, which may be useful to you if you use Spring.

If you are not using Spring, you need to add an additional Spel to your project, you can do:

 ExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext context = new StandardEvaluationContext(dao.getCar()); Power power = parser.parseExpression("engine?.power").getValue(context, Power.class); 

The engine?.power uses a safe navigation operator. In case the engine is null , then the whole expression will evaluate to null .

This solution will work in Java 6.

+1
source

My own approach like this now:

 public class CarDataExtractor { private final Car car; private CarDataExtractor(Car car) { this.car = car; } public static CarDataExtractor on(Car car) { return new CarDataExtractor(car); } public EngineDataExtractor engine() { return car != null && car.getEngine() != null ? EngineDataExtractor.on(car.getEngine()) : EngineDataExtractor.on(null); } public Car self() { return car; } } public class EngineDataExtractor { private final Engine engine; private EngineDataExtractor(Engine engine) { this.engine = engine; } public static EngineDataExtractor on(Engine engine) { return new EngineDataExtractor(engine); } public PowerDataExtractor engine() { return engine != null && engine.getPower() != null ? PowerDataExtractor.on(engine.getPower()) : PowerDataExtractor.on(null); } public Engine self() { return engine; } } ... Power power = CarDataExtractor.on(dao.getCar()).engine().power().self() 

This is because I am limited to Java 6 ...

0
source

Source: https://habr.com/ru/post/1271639/


All Articles