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
	}
}