[Java] Optional - nullPointException을 잘 다뤄보자.

2023. 9. 25. 11:40·Programming Language/Java
반응형

 

Optional 은 null 값을 잘 처리하기 위한 클래스입니다.

 

 

 

without Optional

 

public class SimpleNpeExampleMain {
    public static void main(String[] args) {
        String string = getNullString();

        System.out.println("string=" + string);

        System.out.println(string.toUpperCase());
    }

    private static String getNullString() {
        return null;
    }
}

 

근데 이렇게 당연하게 null 이 터지는 경우는 실제 상황에서 없을 것이다.

좀 더 현실적인 경우를 생각해보자.

 

 

public class MapRepository {

    private Map<String, String> map = new HashMap<>();

    MapRepository() {
        map.put("EXIST_KEY", "value");
    }

    public String getValue(String key) {
        return map.get(key);
    }
}

 

public class WithoutOptionalExampleMain {
    public static void main(String[] args) {
        MapRepository mapRepository = new MapRepository();
        String string = mapRepository.getValue("NOT_EXIST_KEY");

        System.out.println("string=" + string);

        System.out.println(string.toUpperCase());

//        NullPointerException을 피하려면 이렇게 Null 체크를 해야함.
//        if(string != null)
//            System.out.println(string.toUpperCase());
    }
}

 

mapRepository 에 없는 key를 넣어서 getValue() 를 했으니 string 은 null 이 될 것이다.

다라서 string.toUpperCase() 에서 npe 가 발생한다.

 

 

 

 

with Optional

 

Optional 을 왜 사용할까?

 

Object obj = stream.getFirst();

if(obj == null)
	new MyFancyException();

-> Optional 을 사용하지 않았을 때

 

stream.getFirst().orElseThrow(() -> new MyFancyException())

-> Optional 을 사용했을 때    :    좀 더 fancy 한 코드가 완성된다.

 

 

 

이제 Optional 을 잘 사용해보기 위해서,

사용하는 3가지 예제를 보자.

 

예제

public class WithOptionalExampleMain {
    public static void main(String[] args) {
        MapRepository mapRepository = new MapRepository();
        Optional<String> string = mapRepository.getOptionalValue("NOT_EXIST_KEY");
//        Optional<String> string = mapRepository.getOptionalValue("EXIST_KEY");

        string.ifPresentOrElse(
                str -> System.out.println(str.toUpperCase()),               // Optional이 Empty가 아닐 때 실행
                () -> {
                    throw new RuntimeException("키가 존재하지 않습니다."); // Optional이 Empty일 때 실행
                }
        );
    }
}

 

 

예제

public class WithOptionalExampleMain2 {
    public static void main(String[] args) {
        // 이전 코드보다 간결한 코드
        
        MapRepository mapRepository = new MapRepository();
        String string = mapRepository.getOptionalValue("NOT_EXIST_KEY").orElseThrow(
                () -> {throw new RuntimeException("키가 존재하지 않습니다.");}
        );

        System.out.println(string.toUpperCase());
    }
}

 

 

예제

public class WithOptionalExampleMain3 {
    public static void main(String[] args) {
        // Optional의 정적 팩토리 메서드 사용
        
        MapRepository mapRepository = new MapRepository();
        String string = Optional.ofNullable(mapRepository.getValue("NOT_EXIST_KEY"))
                .orElseThrow(RuntimeException::new);

        System.out.println(string.toUpperCase());
    }
}

 

 

 

  • 내가 쓰는 라이브러리의 메서드 반환 타입이 Optional 인 경우
    • 그대로 orElseThrow 같은 메서드로 사용
  • 내가 쓰는 라이브러리의 메서드 반환 타입이 Optional 이 아닌 경우
    • Optional.ofNullable 로 Optional 객체 생성 후, orElseThrow 같은 메서드로 사용

 

 

 

public class ListOptionalExampleMain {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Integer filteredInteger = list.stream()
                .filter(value -> value.equals(100))
                .findFirst()
                .orElseThrow(() -> {
                    throw new RuntimeException("100에 해당하는 요소가 없습니다.");
                });

        System.out.println(filteredInteger);
    }
}

-> stream Api 와 연계해서 사용하면 굉장히 잘 어울린다.

stream 을 사용하면서 있을 수도 있고 없을 수도 있는 상황에, Optional 을 사용할 수 있기 때문이다.

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'Programming Language > Java' 카테고리의 다른 글

[Java] stream API를 예제와 함께 알아보자.  (0) 2023.09.26
[Java] if문이 너무 많다면, 리팩토링을 해보자.  (0) 2023.09.25
[Java] Object 클래스와 주요 메서드 - equals(), hashCode(), toString()  (0) 2023.09.22
[Java] Checked & Unchecked exception 의 차이에 대하여  (0) 2023.09.22
[Java] Enum을 예제로 알아보자.  (0) 2023.09.22
'Programming Language/Java' 카테고리의 다른 글
  • [Java] stream API를 예제와 함께 알아보자.
  • [Java] if문이 너무 많다면, 리팩토링을 해보자.
  • [Java] Object 클래스와 주요 메서드 - equals(), hashCode(), toString()
  • [Java] Checked & Unchecked exception 의 차이에 대하여
Giken
Giken
𝐒𝐲𝐬𝐭𝐞𝐦.𝐨𝐮𝐭.𝐩𝐫𝐢𝐧𝐭𝐥𝐧("𝐇𝐞𝐥𝐥𝐨 𝐖𝐨𝐫𝐥𝐝!");
  • Giken
    개발자 기켄
    Giken
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Programming Language (26)
        • C (3)
        • C++ (2)
        • Java (19)
      • Web (4)
      • Database (1)
        • SQL (5)
      • Spring (10)
      • PHP (7)
      • Linux (1)
      • Server (1)
      • Infra (3)
      • Algorithm (74)
        • 백준 (71)
        • 프로그래머스 (0)
      • 프로젝트 (2)
      • Etc (8)
      • 낙서 (5)
  • 블로그 메뉴

    • GitHub
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    2753
    DB
    백준
    9498
    2588
    SQL고득점키트
    평년
    프로그래머스
    SQL
    윤년
    1330
    C
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Giken
[Java] Optional - nullPointException을 잘 다뤄보자.
상단으로

티스토리툴바