[Java] : 자바에서의 null 처리

dohyoungK·2024년 5월 8일
0

면접 스크립트

목록 보기
26/30

[Java] : 자바에서의 null 처리


Null이란?

null은 변수가 가리키는 주소값이 없다는 것을 표현하기 위한 키워드이다.

하지만 자바에서는 int나 char와 같은 primitive 타입에는 초기화 이전에도 0이나 공백같은 원시값을 저장하고 있기 때문에 null을 대입할 수 없다.

반면에 reference 타입에는 값이 없거나 기본값을 null로 지정한다.

자료형기본값
booleanfalse
char'\u0000'
byte,short,int0
long0
float0.0f
double0.0d
reference valuenull

NPE(NullPointerException)

에러 메시지 NullPointerException은 null 참조로 인해 자바 개발자들이 가장 골치아프게하는 1등 공신이다.

자바에서의 null은 참조가 없는 경우를 뜻하는데, 만약 null을 참조하는 레퍼런스 변수로 객체의 인스턴스 메서드를 호출하는 등의 객체 코드를 실행하려 할 때 NPE가 발생한다.

NPE 발생 시나리오

public class Person {
    private Game game;
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public Game getGame() {
        return game;
    }
}

public class Game {
    private Weapon weapon;

    public Weapon getWeapon() {
        return weapon;
    }
}

public class Weapon {
    public String printWeapon() {
        return "sword";
    }
}

public static void main(String[] args) {
	Person person = new Person("aaa");
        
    person.getGame().getWeapon().printWeapon();
}

코드를 실행해보면 NPE가 발생하게 된다.

new Person()이 초기화 될 때, 인스턴스 객체인 Game에 값이 들어가지 않아 person.getGame()의 반환값이 null이기 때문에 null.getWeapon() 메서드가 작동하지 않기 때문이다.

NPE 방지하는 방법

Java8 이전에는 중첩 조건문을 사용해 회피했다.

public static void main(String[] args) {
	Person person = new Person("aaa");
        
    Game game = person.getGame();
    if (game != null) {
        Weapon weapon = game.getWeapon();
        if (weapon != null) {
            String w = weapon.printWeapon();
        }
    }
}

이러한 방식은 메서드가 많아질수록 if문 역시 증가되어 코드 가독성 측면에서 좋지 않은 방식이라 할 수 있다.


Optional 클래스

Java8이 등장하며 null 처리를 정식으로 지원하는 java.util.Optional 클래스가 추가되었다.

public final class Optional<T> {
 
   	/**
   	*if non-null, the value, if null, indicates no value is present
   	*/
   	private final T value;
}

Optional 클래스는 존재할수도 하지않을수도 있는 객체, null이 될 수도 있는 객체를 감싸는 래퍼 클래스이다.

public static void main(String[] args) {
	Person person = new Person("aaa");
        
    Optional<String> optionalWeapon = Optional.ofNullable(person)
                .map(Person::getGame)
                .map(Game::getWeapon)
                .map(Weapon::printWeapon);
}

Optional을 사용하면 이전의 중첩 조건문을 위와 같이 간단하게 바꿀 수 있다.

Optional의 단점

  • NullPointerException 대신 NoSuchElementException이 발생할 수 있다.
  • Optional을 남용하면 코드의 가독성이 오히려 떨어질 수 있다.
  • 시간적, 공간적 비용이 증가할 수 있다.

올바른 Optional 사용법

  • Optional 변수에 null을 할당하지 마라
  • 값이 없을 때 Optional.orElseX()로 반환하라
  • 단순히 값을 얻으려는 목적으로만 Optional을 사용하지 마라
  • 생성자, 수정자, 메서드 파라미터 등으로 Optional을 넘기지 마라
  • Collection의 경우 Optional이 아닌 빈 Collection을 사용하라
  • 반환 타입으로만 사용하라

0개의 댓글