티스토리 뷰

개발

Java8 - Null 체크를 Optional로 대체하기

기억고양이 2023. 3. 2. 22:43
반응형

 

이전에 Optional에 대해 끄적인 기록이 있다. 지금 보면 아무것도 모르고 쓴 티가 많이 난다. (https://insertintoblog.tistory.com/18)

 

어느 순간 어떻게 사용하는지 조금 더 알아서 끄적인다.

결론부터 바로 설명하면 Optional은 if 문을 사용한 Null 체크 지옥에서 탈출하고 싶을 때 사용할 수 있는 방법이다.

 

정상적으로 짰다고 가정하는 다음 소스를 보자.

 

private String geniusTest (String genius) {
    // Null 체크
    if (genius == null) {
        genius = "얘는 머리가 비었습니다";
    }

	{...} // genius 란 스트링을 다루는 로직이 있다고 치고

	genius = genius.subString(0, 2);
}

 

  1. if 문에서 Null 체크를 하고
  2. 중간에 무언가 로직 처리 후
  3. subString을 호출한다.

별 거 없는 소스다.

 

 

하지만 파라미터가 많아질 경우 if 문으로 도배를 하게 된다.

 

private String geniusTest (String genius, String genius1, String genius2, String genius3) {
	// Null 체크
    if (genius == null) {
        genius = "얘는 머리가 비었습니다";
    }
    if (genius1 == null) {
        genius = "첫째는 머리가 비었습니다";
    }
    if (genius2 == null) {
        genius = "둘째도 머리가 비었습니다";
    }    
    if (genius3 == null) {
        genius = "너도 머리가 비었습니다";
    }
    
    
	{...} // genius 란 스트링을 다루는 로직이 있다고 치고

	genius = genius.subString(0, 2);
	genius1 = genius1.subString(0, 3);
	genius2 = genius2.subString(0, 4);
	genius3 = genius3.subString(0, 5);
}

 

(물론 @NotNull 같은 어노테이션을 사용할 수도 있겠지만)

예제를 대강 만들어서 그렇지, 현실은 if 문 내부가 이리저리 복잡한 경우도 많다.

 

이럴때 Optional을 사용해 로직 생성을 줄이고 소스를 간결하게 쓸 수 있다.


private String geniusTest (String genius, String genius1, String genius2, String genius3) {
	// Null 체크
	genius = Optional.ofNullable(genius).orElseGet(() -> "얘는 머리가 비었습니다");
	genius1 = Optional.ofNullable(genius1).orElseGet(() -> "첫째는 머리가 비었습니다");
	genius2 = Optional.ofNullable(genius2).orElseGet(() -> "둘째도 머리가 비었습니다");
	genius3 = Optional.ofNullable(genius3).orElseGet(() -> "너도 머리가 비었습니다");
    
	{...} // genius 란 스트링을 다루는 로직이 있다고 치고

	genius = genius.subString(0, 2);
	genius1 = genius1.subString(0, 3);
	genius2 = genius2.subString(0, 4);
	genius3 = genius3.subString(0, 5);
}

아니 이게 뭐야

 

나처럼 Java 8 이전 스타일로만 공부를 했다면 이 소스는 다소 당황스러울 수 있다..

간단히 설명하면 if문을 한 줄로 줄인 새로운 코드 스타일이라고 할 수 있다. (람다식 OR 함수형 프로그래밍 검색)

 

우선 Optional.ofNullable 을 사용하려면 반드시 다음처럼 구성해줘야 동작한다.

  1. Null 체크할 값을 써줌.
  2. Null일 경우 대체값이 필요함.
  3. (선택) 메서드 체이닝을 통해 연속적으로 메서드를 붙일 수 있다.

 


 

genius = Optional.ofNullable(genius).orElseGet(() -> "얘는 머리가 비었습니다"); 을 풀어서 써보면

 

  1. Null일 가능성이 있는 genius를 미리 까보고
  2. (ofNullable) Null이 아니라면 그대로 리턴, (Null 체크할 값에 해당)
  3. (orElseGet) Null이라면 "얘는 머리가 비었습니다"를 리턴. (Null일 경우 대체값)

정확한 해석은 아니지만 처음엔 이런식으로 이해하는게 쉽다.

보다시피 한 줄에 Null 체크, Null일때 반환받을 값, 아니면 원래 값 그대로를 받는 소스를 쓸 수 있다.

 

게다가 if문을 사용하면 IDE에서 오류체크가 불가하기 때문에 잘못된 구문을 넣는 경우도 있는데

대체값을 기입해주지 않아서 발생하는 오류다. 이렇게 IDE에서 오류체크까지 해주므로 실수를 줄일 수 있다.


처음엔 이해가 어려울 수 있으나

소스중의 if문을 optional로 전환시켜보면 optional의 편리함과 소스 구조가 어떻게 되는지 차차 이해가 될 것이라고 생각한다.

 

나도 그렇게 이해하는데 시간이 걸렸으니깐..

 

그리고 Optional을 파보면 파볼수록 지금까지 본 예제는 새발의 피일 뿐이다.

ofNullable 을 쓰고 자동완성 되는 구문을 살펴보면 목록이 엄청 많다. 이거를 한번에 익히기도 어렵고, 익힐 필요도 없다.

그나마 유용한 메서드는 orElseThrow 정도이다.

이름에서 감이 오겠지만 null일 경우 특정 예외를 발생시킬 수 있다.

 

나머지의 경우 람다식 or 함수형 프로그래밍을 이해해야 써먹지, 무턱대고 쓰기에는 쉽지 않았던것 같다.

 

(사실 Optional.ofNullable로 사용할수도 있고 Optional.of를 사용할 수도 있다.

둘이 이름은 비슷하지만 기능이 좀 다른데 이런 것들은 천천히 배워나가자.)

 

반응형