New Optional Class in Java 8, Not a Panacea for NullPointerException
- From the sandbox
- Tutorial
The Java 8 release introduces a new class
We have
But what if it is completely forbidden to assign equal values to one or another field of a class
So, we begin to describe the main features of this innovation.
To start, I’ll give an example of a class using
As you can see, when setting fields to a class of values, through the “set” methods, we use static methods of the class
These methods are used to create objects of the type
Often, checking for
If we try to access this field directly through a chain of objects and provided that the transmitted object for some reason has come equal,
And now everything is the same, but using
A lot more concise, isn't it?
The method
The same actions, but using
As it was before:
The same, but using
And finally, a few more methods for pointing out the “beauty” in the code.
As it was before:
The same, but using
Or, if you do not want to create an object, you can throw an exception:
Naturally, it
And also, undoubtedly, it
This concludes my short description of this innovation, thanks for reading! You can find more information on this topic from the links below.
Information for further study:
Optional
to help developers with processing NullPointerException
. We have
NullPointerException
met many, and in many cases, this very unpleasant exception forces us to debug the code in order to understand in which place, one of your predecessors (and possibly you) did not put the notorious check on null
. But what if it is completely forbidden to assign equal values to one or another field of a class
null
? Java naturally does not forbid us to do this, but with Optional
it it becomes a little more convenient and visual. So, we begin to describe the main features of this innovation.
Creating Optional Objects
To start, I’ll give an example of a class using
Optional
:import java.util.Date;
import java.util.Optional;
public class Person {
private Optional firstName;
private Optional secondName;
private Optional age;
private Optional address;
public Optional getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = Optional.ofNullable(firstName);
}
public Optional getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = Optional.of(secondName);
}
public Optional getAge() {
return age;
}
public void setAge(Integer age) {
this.age = Optional.ofNullable(age);
}
public Optional getAddress() {
return address;
}
public void setAddress(PersonAddress address) {
this.address = Optional.of(address);
}
}
As you can see, when setting fields to a class of values, through the “set” methods, we use static methods of the class
Optional - of(), ofNullable())
. These methods are used to create objects of the type
Optional
; the following are examples of such creating objects:/** Создание Optional объектов */
//Пустой Optional объект
Optional optionalPerson = Optional.empty();
//Optional объект с ненулевым значением
Optional optionalNonNull = Optional.of(somePerson);
//Optional объект с возможностью нулевого значения
Optional optionalNullable = Optional.ofNullable(somePerson);
Using Optional to Eliminate Redundant Code
Often, checking for
null
objects that are transmitted or processed in various methods takes a lot of lines of code if you need to work not only with the transferred object, but with the field of the object, which in turn contains another field, for example, a text description. If we try to access this field directly through a chain of objects and provided that the transmitted object for some reason has come equal,
null
we will get it NullPointerException
, so for a start we need to check each object on null
and only 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");
A lot more concise, isn't it?
Actions on an object using the ifPresent () method
The method
ifPresent()
also allows you to eliminate some redundancy of the code, of the following form: if(person != null) {
System.out.println(person);
}
The same actions, but using
Optional
:person.ifPresent(System.out::println);
Actions on an object using isPresent ()
isPresent()
It doesn’t give us much benefit in eliminating code redundancy, but it does give a little more information to the 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 on an object using orElse (), orElseThrow ()
And finally, a few more methods for pointing out the “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, it
Optional
does not give any guarantee of getting rid of, NullPointerException
and all the checks for null
could be described earlier, but with Optional
it the actions become faster and easier, since additional methods for checking the object or checking and some further actions with the object are already described and we just need to use them in your code. And also, undoubtedly, it
Optional
helps to give more information to the code, to increase its readability. This concludes my short description of this innovation, thanks for reading! You can find more information on this topic from the links below.
Information for further study: