Optional?

🌎·2023년 5월 20일
0

스프링 공부

목록 보기
6/11

Optional

Optional 클래스는 Integer나 Double 클래스처럼 'T'타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)입니다.
따라서 Optional 인스턴스는 모든 타입의 참조 변수를 저장할 수 있습니다.
출처 : 코딩의 시작, TCP School

우리는 코딩을 하다가 NullPointException(이하, NPE)를 많이 접하게 된다.
항상 코드를 짜다 보면, 나같은 경우도 가장 많이 걱정하는게 NPE이다. 그러다보니 사실 많이 번거롭고 코드도 길어지고... 나름 스트레스다...ㅠㅠ
특히 생각하지 못한 곳에서 NPE가 터지면.... 😵‍💫

NULL을 개발한 사람도 나중에는 자신이 "10억불 짜리 큰 실수"를 했으며, NULL을 만든 것을 후회한다고 하였다.

NPE를 피하기 위해 우리는 아래와 같이 항상 null체크를 해주어야만 했다.


	Board board = getBoard(); //Board 객체를 가져오는 어떤 함수라고 가정
	if(board != null) {
		User user = board.getUser();
		if(user != null) {
			// 하고 싶은 일 작성
		}
	}

이렇게 객체안의 객체도 계속 null체크를 해주어야 NPE로부터 마음이 편해질 수 있었다.
그런데 Optional이 등장하면서 아주 편리해졌다.

	Optional<Board> board = Optional.ofNullable(getBoard());
	Optional<User> user = board.map(Board::getUser);

	board.

나같은 경우는 iOS 개발을 시작하면서 Swift를 공부했었는데, 거기에서 Optional이 있어서 아주 편했던 기억이 난다.(문법 자체는 그동안 공부했던 java나 c와 같은 언어와 달라서 당황했지만...;;)
아무튼 오늘은 이 Optional에 대해 한 번 공부해보려고 한다.

Optional 선언

1. static Optional empty()

비어있는 객체를 리턴해준다.
Null 값이 올 수도 있는 변수의 자료형을 제너릭 타입으로 선언한다.

	Optional<T> opt = Optional.empty(); //Null이 올 수도 있음

2. static Optional of(T value)

Null이 아닌 명시된 값을 가지고 있는 Optional 객체를 반환한다.
Null인 경우 NPE를 던진다.

	Optional<String> opt = Optional.of("Apple");

3. static Optional ofNullable(T value)

명시된 값이 Null이 아니면, 명시된 값을 가지는 Optional 객체를 반환한다.
명시된 값이 Null이면, 비어있는 Optional 객체를 반환한다.

	Optional<String> opt = Optional.ofNullable(null);

Optional 메소드

1. T get()

Optional 객체에 저장된 값을 반환한다.

2. T isPresent()

저장된 값이 존재하면 true를 반환하고, 존재하지 않으면 false를 반환한다.

3. T orElse(T other)

저장된 값이 존재하면 그 값을 반환하고, 존재하지 않으면 인수로 전달된 값을 반환한다.

4. T orElseGet(Supplier<? extends T> other)

저장된 값이 존재하면 그 값을 반환하고, 존재하지 않으면 인수로 전달된 람다 표현식의 결과값을 반환한다.

5. T orElseThrow(Supplier<? extends X> exceptionSupplier)

저장된 값이 존재하면 그 값을 반환하고, 존재하지 않으면 인수로 전달된 예외를 발생시킨다.

6. Optional or(Supplier<? extends Optional<? extends T>> supplier) - java 9

중간처리 메서드로 기본값을 제공할 수 있는 공급자 함수를 정의할 수 있다. 기존에 제공중인 .orElseGet()과 유사하지만, 중간에 체이닝을 통해 우선순위를 결정할 수 있다. 물론 .or() 연산 중에 비어있는 옵셔널이 된다면 다음 .or() 메서드로 진행하게 된다.

  String result = Optional.ofNullable("test")
          .filter(value -> "filter".equals(value))
          .or(Optional::empty)
          .or(() -> Optional.of("second"))
          .orElse("final");
  System.out.println(result); // print 'second'

7. void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) - java 9

첫번째 매개변수인 action은 유효한 객체를 받을 경우 실행하고, 두번째 매개변수인 emptyAction은 유효한 객체를 받지 못한 경우 실행한다.

  Optional.ofNullable(null)
      .ifPresentOrElse(value -> System.out.println(value), () -> System.out.println("null")); // print 'null'

8. Stream stream() - java 9

Optional 객체를 Stream 객체로 전환한다.

List<String> result = List.of(1, 2, 3, 4)
  .stream()
  .map(val -> val % 2 == 0 ? Optional.of(val) : Optional.empty())
  .flatMap(Optional::stream)
  .map(String::valueOf)
  .collect(Collectors.toList());
System.out.println(result); // print '[2, 4]'

Optional<List> 와 같이 사용하면 Optional도 null체크를 하고 List도 null체크를 해야하기 때문에 가독성이 떨어진다. 항상 List를 사용할 때에는 List를 채워주는 것이 좋다.

  List data = Optional.ofNullable(somethingList).orElse(Collections.emptyList());
  if (!data.isEmpty()) {
      // do something...
  }

끝-*


참고
자바 옵셔널
[JAVA] Optional이란?

profile
영차영차

0개의 댓글