Some stuffs related to NPE Refer1 Refer2
1. Optional
- This class will be an container object which may or may not contain a non-null value
- Examples:
// Potential dangers of null
String version = computer.getSoundcard().getUSB().getVersion();
// Solution 1: Ugly due to the nested checks, decreasing the readability
String version = "UNKNOWN";
if(computer != null){
Soundcard soundcard = computer.getSoundcard();
if(soundcard != null){
USB usb = soundcard.getUSB();
if(usb != null){
version = usb.getVersion();
}
}
}
// Solution 2(JavaSE7):
String version = computer?.getSoundcard()?.getUSB()?.getVersion();
String version =
computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";
// Solution 3 (JavaSE8)
public class Computer {
private Optional<Soundcard> soundcard;
public Optional<Soundcard> getSoundcard() { ... }
...
}
public class Soundcard {
private Optional<USB> usb;
public Optional<USB> getUSB() { ... }
}
public class USB{
public String getVersion(){ ... }
}
String name = computer.flatMap(Computer::getSoundcard)
.flatMap(Soundcard::getUSB)
.map(USB::getVersion)
.orElse("UNKNOWN");
1.1 Creating Optional objects - Optional.of(var)/ Optional.ofNullable(var)
SoundCard soundCard = new SoundCard();
Optional<SoundCard> sc = Optional.of(soundCard); // NPE if soundCard is null
Optional<SoundCard> sc = Optional.ofNullable(soundCard); // may hold a null value
1.2. Check presenting - .ifPresent(//)
// ugly code
SoundCard soundcard = ...;
if(soundcard != null){
System.out.println(soundcard);
}
// solution 1
SoundCard soundcard = ...;
if(soundcard != null){
System.out.println(soundcard);
}
// solution 2
if(soundcard.isPresent()){
System.out.println(soundcard.get());
}
1.3. Default - .orElse/ .orElseThrow
// ugly code
Soundcard soundcard =
maybeSoundcard != null ? maybeSoundcard
: new Soundcard("basic_sound_card");
// solution 1
Soundcard soundcard = maybeSoundcard.orElse(new Soundcard("defaut")); // default value
Soundcard soundcard = maybeSoundCard.orElseThrow(IllegalStateException::new); // default throw E
…
2. Null-Safety Annotations
- This is the null-safety feature produces warnings at compile time, which help prevent NPE at runtime.
2.1. @NonNull, @Nullable
- We can use this to declare non-null(null) constraint.
- Examples:
import org.eclipse.jdt.annotation.*;
public class Person {
@NonNull
private String fullName;
void setFullName(String fullName) {
fullName = null; // warning or error
this.fullName = fullName; //warning or error
}
}
public class Person {
@Nullable
private String fullName;
void setFullName(String fullName) {
fullName = null;
this.fullName = fullName;
}
}
public class Person {
private String fullName;
void setFullName(@NonNull String fullName) {
this.fullName = fullName;
}
void setFullNameNull() {
this.setFullName(null); // Error here
}
}