Java
Programming Language
Backend
☕️[Java] ☕️[Java] Java Optional이란 무엇일까요?
-
Optional
은 Java 8에서 도입된 null 값을 안전한게 처리하기 위한 클래스입니다.
-
null 값을 직접 다루는 것에 대한 문제점(예:
NullPointException
)을 줄이기 위해 설계되었으며, 값이 존재할 수도 있고, 존재하지 않을 수도 있는 상황을 표현할 수 있도록 도와줍니다.
1️⃣ Optional
의 주요 목적.
1️⃣ null 처리의 안정성
- Java에서 null을 반환하거나 사용하는 것은 매우 흔한 일이지만, 잘못된 null 처리는
NullPointException
을 유발할 수 있습니다.
-
Optional
을 사용하면 이런 문제를 예방할 수 있습니다.
2️⃣ 의도 명확성.
-
Optional
을 사용하면, 메서드의 반환값이 값이 없을 수 있음을 명확하게 표현할 수 있습니다.
- 개발자는 반환값이
Optional
타입일 때 값이 없는 경우에 대한 처리를 고려할 수 있습니다.
3️⃣ 코드의 가독성 및 유지보수성.
-
Optional
은 null 체크를 일일이 하는 대신, 값이 없을 수 있는 상황을 안전하게 다루기 위한 여러 메서드를 제공합니다.
- 이를 통해 코드의 가독성이 좋아지고 유지보수하기 쉬워집니다.
2️⃣ Optional의 생성 방법.
1️⃣ Optional.of(T value)
-
null이 아닌 값으로
Optional
객체를 생성합니다.
- 값이 null일 경우
NullPointException
이 발생합니다.
Optional<String> optional = Optional.of("Hello");
2️⃣ Optional.ofNullable(T value)
- 전달된 값이 null일 수도 있고, 아닐 수도 있는 경우 사용합니다.
- 값이 null이면
Optional.empty()
반환하고, 그렇지 않으면 Optional.of(value)
와 동일한 동작을 합니다.
Optional<String> optional = Optional.ofNullable(null); // 비어있는 Optional 반환
3️⃣ Optional.empty()
-
비어있는 Optional 객체를 생성합니다.
- 값이 없음을 명시적으로 나타낼 때 사용합니다.
Optional<String> emptyOptional = Optional.empty();
3️⃣ Optional의 주요 메서드.
1️⃣ isPresent()
- Optional에 값이 있으면
true
, 없으면 false
를 반환합니다.
Optional<String> optional = Optional.of("Hello");
if (optional.isPresent()) {
System.out.println(optional.get()); // "Hello" 출력
}
2️⃣ ifPresent(Consumer<T> action)
- Optional에 값이 있으면 해당 값으로 지정된 동작을 수행합니다.
- 값이 없으면 아무 일도 하지 않습니다.
Optional<String> optional = Optional.of("Hello");
optional.ifPresent(value -> System.out.println(value)) // "Hello" 출력
3️⃣ get()
- Optional에 저장된 값을 반환합니다.
- 값이 없으면
NoSuchElementException
이 발생하므로, 주의해서 사용해야 합니다.
Optional<String> optional = Optional.of("Hello");
String value = optional.get(); // "Hello"
4️⃣ orElse(T other)
- Optional에 값이 있으면 그 값을 반환하고, 값이 없으면 기본값을 반환합니다.
Optional<String> optional = Optional.empty();
String value = optional.orElse("Default"); // "Default"
5️⃣ orElseGet(Supplier<? extends T> supplier)
- Optional에 값이 있으면 그 값을 반환하고, 값이 없으면 람다 표현식이나 메서드를 통해 기본값을 제공할 수 있습니다.
Optional<String> optional = Optional.empty();
String value = optional.orElseGet(() -> "Generated Default"); // "Generated Default"
6️⃣ orElseThrow(Supplier<? extends X> exceptionSupplier)
- Optional에 값이 있으면 그 값을 반환하고, 값이 없으면 지정한 예외를 던집니다.
Optional<String> optional = Optional.empty();
String value = optional.orElseThrow(() -> new IllegalArgumentException("Value not found")); // 예외 발생
7️⃣ map(Function<? super T, ? extends U> mapper)
- Optional에 값이 있으면, 해당 값에 대해 함수형 변환을 적용한 결과를 새로운 Optional로 변환합니다.
- 값이 없으면 빈 Optional을 반환합니다.
Optional<String> optional = Optional.of("Hello");
Optional<Integer> length = optional.map(String::length); // "Hello"의 길이인 5를 포함한 Optional 반환
8️⃣ flatMap(Function<? super T, Optional<U>> mapper)
-
map()
과 유사하지만, 중첩된 Optional을 평평하게 만듭니다.
-
Optional<Optional<T>>
형태가 아닌 Optional<T>
를 반환합니다.
Optional<String> optional = Optional.of("Hello");
Optional<Integer> length = optional.flatMap(val -> Optional.of(val.length()));
4️⃣ Optional 사용 예시.
1️⃣ Optional을 이용한 안전한 null 처리.
public Optional<User> findUserById(Long id) {
User user = userRepositoty.findById(id);
return Optional.ofNullable(user);
}
public void printUserName(Long userId) {
Optional<User> userOpt = findUserById(userId);
userOpt.ifPresent(user -> System.out.println(user.getName()));
}
2️⃣ 기본값 제공.
Optional<String> optional = Optional.empty();
String value = optional.orElse("Default Value"); //"Default Value" 반환
5️⃣ Optional을 사용하지 않아야 할 경우.
-
컬렉션 타입
- Optional을 사용하여 빈 리스트나 배열을 표현하기보다는, 단순히 빈 컬렉션을 반환하는 것이 더 일반적이고 권장됩니다.
-
필드 선언
- 클래스의 필드로 Optional을 사용하는 것은 메모리 오버헤드가 발생할 수 있어 권장하지 않습니다.
- Optional은 반환 타입으로 사용하는 것이 좋습니다.
-
필수 값
- 절대 null이 되어서는 안 되는 필드나 매개변수에 Optional을 사용할 필요는 없습니다.
6️⃣ 요약.
-
Optional
은 null 값으로 인한 문제를 예방하고, 안전하게 값을 처리할 수 있도록 설계된 클래스입니다.
- 값이 있을 수도, 없을 수도 있는 상황을 더 명확하게 표현하며, 다양한 메서드를 통해 안전하게 값의 여부를 확인하고 처리할 수 있게 도와줍니다.
- 이를 통해 코드의 가독성과 유지보수성이 크게 향상됩니다.