Java의 Optional 클래스는 Java 8에서 추가된 클래스 중 하나로, null 처리를 보다 명시적으로 하고, NullPointerException(NPE) 문제를 방지하기 위해 도입되었다. Optional은 값이 있을 수도 있고 없을 수도 있는 상황을 나타내는 컨테이너 객체로 사용된다.
null*을 반환하는 대신 값이 있거나 없는 상태**를 표현할 수 있다.Optional 객체는 여러 가지 방법으로 생성할 수 있다.
empty()빈 Optional 객체를 생성한다.
Optional<String> emptyOptional = Optional.empty();
of()값이 반드시 있어야 할 때 사용한다. 값이 null이면 NullPointerException이 발생한다.
Optional<String> optional = Optional.of("Hello");
ofNullable()값이 있을 수도 있고 없을 수도 있는 경우 사용한다. 값이 null이면 빈 Optional 객체를 반환한다.
Optional<String> optional = Optional.ofNullable(null); // 빈 Optional
Optional<String> optional2 = Optional.ofNullable("Hello"); // 값이 있는 Optional
Optional 클래스는 값을 안전하게 다룰 수 있도록 다양한 메서드를 제공한다.
isPresent() / isEmpty()isPresent(): 값이 존재하면 true, 없으면 false를 반환한다.isEmpty(): 값이 없으면 true, 있으면 false를 반환한다.Optional<String> optional = Optional.ofNullable("Hello");
System.out.println(optional.isPresent()); // true
System.out.println(optional.isEmpty()); // false
get()Optional에 값이 존재하면 값을 반환한다. 값이 없으면 예외를 발생시킨다.
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.get()); // Hello
⚠️ 주의: 값이 없는 경우 NoSuchElementException이 발생하므로, 사용 시 isPresent()로 값이 있는지 확인해야 한다.
orElse()값이 존재하면 해당 값을 반환하고, 없으면 기본값을 반환한다.
Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.orElse("Default")); // Default
orElseGet()값이 없을 때 실행할 동작을 람다식으로 정의할 수 있다.
Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.orElseGet(() -> "Generated Value")); // Generated Value
orElseThrow()값이 없으면 지정된 예외를 발생시킨다.
Optional<String> optional = Optional.ofNullable(null);
optional.orElseThrow(() -> new IllegalArgumentException("Value not found!"));
ifPresent()값이 존재하면 특정 동작을 실행한다.
Optional<String> optional = Optional.of("Hello");
optional.ifPresent(value -> System.out.println("Value: " + value)); // Value: Hello
map()값이 존재하면 값을 변환하고, 빈 Optional 객체는 그대로 반환한다.
Optional<String> optional = Optional.of("Hello");
Optional<Integer> length = optional.map(String::length);
System.out.println(length.get()); // 5
flatMap()map()과 유사하지만, 반환 값이 이미 Optional인 경우에 중첩을 방지한다.
Optional<String> optional = Optional.of("Hello");
Optional<String> upper = optional.flatMap(value -> Optional.of(value.toUpperCase()));
System.out.println(upper.get()); // HELLO
기존 방식:
public String findName() {
return null; // 값이 없으면 null 반환
}
Optional 방식:
public Optional<String> findName() {
return Optional.ofNullable(null); // 값이 없으면 Optional.empty()
}
Optional<String> name = findName();
String result = name.orElse("Unknown");
System.out.println(result);
findName().ifPresent(name -> System.out.println("Name: " + name));
Optional은 반환값이나 로직 처리에 사용하며, 클래스의 필드로 사용하면 불필요한 복잡성을 초래한다.get()을 남용하지 않는다.get()은 값이 없는 경우 예외를 발생시키므로 orElse(), orElseGet(), 또는 ifPresent()를 사용하는 것이 더 안전하다.Optional은 성능 문제를 고려해야 한다.Optional은 객체이기 때문에 기본 타입(예: int, double)과 비교했을 때 오버헤드가 있을 수 있다. 기본 타입에는 OptionalInt, OptionalDouble 등을 사용한다.Optional은 null 대신 사용하여 안전하게 값을 다룰 수 있는 도구다.Optional을 사용하는 것은 적합하지 않으므로, 상황에 맞게 사용하는 것이 중요하다.