📜 ⬆️ ⬇️

New Optional class in Java 8, not a panacea for NullPointerException

In the release of Java 8, a new class called Optional to help developers handle NullPointerException .

Many have met with NullPointerException and in many cases, this very unpleasant exception makes debugging code to understand where some of your predecessors (and possibly you) did not put the notorious null test.

And what if at all to prohibit to assign to one or another class field values ​​equal to null ? Naturally, Java does not forbid us to do this, but with Optional it becomes a bit more convenient and clearer.
')
So, let's proceed to the description of the main features of this innovation.

Creating Optional Objects

To begin with, I will give an example of a class using Optional :

 import java.util.Date; import java.util.Optional; public class Person { private Optional<String> firstName; private Optional<String> secondName; private Optional<Integer> age; private Optional<PersonAddress> address; public Optional<String> getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = Optional.ofNullable(firstName); } public Optional<String> getSecondName() { return secondName; } public void setSecondName(String secondName) { this.secondName = Optional.of(secondName); } public Optional<Integer> getAge() { return age; } public void setAge(Integer age) { this.age = Optional.ofNullable(age); } public Optional<PersonAddress> getAddress() { return address; } public void setAddress(PersonAddress address) { this.address = Optional.of(address); } } 

As you can see, when setting the value class fields, using the “set” methods, we use the static methods of the Optional - of(), ofNullable()) class Optional - of(), ofNullable()) .

These methods are used to create objects of type Optional , below are examples of how to create objects:

 /**  Optional  */ // Optional  Optional<Person> optionalPerson = Optional.empty(); //Optional     Optional<Person> optionalNonNull = Optional.of(somePerson); //Optional      Optional<Person> optionalNullable = Optional.ofNullable(somePerson); 

Using Optional to eliminate redundancy code

Often, checking for null objects that are transmitted or processed in various methods takes up many lines of code if you need to work not only with the transferred object, but with the object field, which in turn contains another field, for example, a text description.

If you try to access this field directly through a chain of objects and provided that the object passed for some reason came null we get a NullPointerException , so first we need to check each object for null and then take the text field we need:

 Person person = getDefaultPerson(); if (person != null) { PersonAddress personAddress = person.getAddress(); if (personAddress != null) { PersonAddressStreet street = personAddress.getStreet(); if(street != null) { streetName = street.getStreetName(); } else { streetName = "EMPTY"; } } } 

And now everything is the same, but using Optional :

 String streetName = person.flatMap(Person::getAddress) .flatMap(PersonAddress::getStreet) .map(PersonAddressStreet::getStreetName) .orElse("EMPTY"); 

Much more concise, is not it?

Actions with an object using the ifPresent () method

The ifPresent() method also allows you to eliminate some redundancy of code like the following:

  if(person != null) { System.out.println(person); } 

The same actions, but using Optional :

 person.ifPresent(System.out::println); 

Actions with an object using isPresent ()

isPresent() does not provide us with great benefits in eliminating code redundancy, but it gives a little more information to written code.

As it was before:

 if(person != null) { System.out.println(person) } else { System.out.println("Person not found!"); } 

The same, but using Optional :

 if (person.isPresent()) { System.out.println(person.get()); } else { System.out.println("Person not found!"); } 

Actions with an object using orElse (), orElseThrow ()

And finally, a few more methods for targeting "beauty" in the code.

As it was before:

 Person personNew = person != null ? person : new Person(); 

The same, but using Optional :

 Person personNew = person.orElse(new Person()); 

Or, if you do not want to create an object, you can throw an exception:

 Person personNewThrow = person.orElseThrow(Exception::new); 

Conclusion

Naturally, the Optional does not give any guarantee of getting rid of NullPointerException and all null checks could have been described before, but with Optional these actions become faster and simpler, as additional methods for checking an object or checking and some further actions with an object are already described and we just have to use them in our code.

And also, of course, Optional helps to make the code more informative and make it more readable.

This concludes my short descriptions of this innovation, thanks for reading! Further information on this topic can be found at the links below.

Information for further study:

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


All Articles