Details about the known misuse from the MUBench dataset.
Description:
Uses Optional.get() without prior check of isPresent() within Optional.map(), which may cause a NullPointerException. Safe way is to use flatMap instead, which takes care of potential null values.
class HundredAndOneApproach.SameOldImperativeStyle {
public String getPersonCarInsuranceName(Person person) {
String name = "Unknown";
if (ofNullable(person).isPresent()) {
if (person.getCar().isPresent()) {
if (person.getCar().get().getInsurance().isPresent()) {
name = person.getCar().get().getInsurance().get().getName();
}
}
}
return name;
}
}
class HundredAndOneApproach.UsingIfPresentInSameImperativeWayWithDirtyHack {
public String getPersonCarInsuranceName(Person person) {
final StringBuilder builder = new StringBuilder();
ofNullable(person).ifPresent(
p -> p.getCar().ifPresent(
c -> c.getInsurance().ifPresent(
i -> builder.append(i.getName())
)
)
);
return builder.toString();
}
}
class HundredAndOneApproach.UsingMapWithUncheckedGet {
public String getPersonCarInsuranceName(Person person) {
return ofNullable(person)
.map(Person::getCar)
.map(car -> car.get().getInsurance())
.map(insurance -> insurance.get().getName())
.orElse("Unknown");
}
}
class HundredAndOneApproach.UsingMapWithOrElseEmptyObjectToFixUncheckedGet {
public String getPersonCarInsuranceName(Person person) {
return ofNullable(person)
.map(Person::getCar)
.map(car -> car.orElseGet(Car::new).getInsurance())
.map(insurance -> insurance.orElseGet(Insurance::new).getName())
.orElse("Unknown");
}
}
Code with Pattern(s):
class UsingFlatMap {
public String getCarInsuranceNameFromPersonUsingFlatMap(Person person) {
return ofNullable(person)
.flatMap(Person::getCar)
.flatMap(Car::getInsurance)
.map(Insurance::getName)
.orElse("Unknown");
}
}