간단 설명
Optional 은 자바에서 제공하는 특별한 객체로, 값이 있을 수도 있고 없을 수도 있다를 명확히 표현하기 위해 사용합니다.
즉, 어떤 값이 null 일 때 발생할 수 있는 문제를 예방하기 위해 만든 것이라고 생각하시면 됩니다.
Optional 클래스는 Java 8 version부터 지원하는 기능입니다.
필요한 이유
null 값을 처리하는 코드는 문제가 생기기 쉽습니다.
자바에서는 만약 null 값을 사용하려고 하면 NullPointerException 오류가 발생합니다. 이런 오류를 예방하기 위해 전에는 코드에 많은 null 체크를 넣곤 했습니다.
// null 체크 없는 코드
String name = null;
// 프로그램이 이 부분에서 오류 발생 (NullPointerException)
System.out.println(name.toUpperCase());
// null 체크 추가한 코드
String name = null;
if (name != null) {
System.out.println(name.toUpperCase());
} else {
System.out.println("Name is null.");
}
위 코드처럼 값이 null 인지 확인하는 코드를 항상 넣어야 했습니다.
하지만 이렇게 하면 코드가 복잡해지고 실수할 가능성도 높아지기 때문에 Optional이라는 기능이 추가됐습니다.
Optional 이란?
Optional 이란 값을 감싸는 상자와 같습니다.
값이 있으면 상자 안에 값을 넣고 값이 없으면 상자는 비어있음을 나타냅니다.
이를 통해, 값이 존재할 수도 있고 없을 수도 있다는 사실을 명확히 표현할 수 있습니다.
Optional 클래스는 아래와 같이 value 에 값을 저장하기 때문에 값이 null 이더라도 바로 NPE 가 발생하지 않으며, 클래스이기 때문에 각종 메서드를 지원해 줍니다.
public final class Optional<T> {
// If non-null, the value; if null, indicates no value is present
private final T value;
...
}
Optional의 주요 기능
Optional.of(value)
값이 null 이 아니라고 확신할 때 사용합니다.
만약 null 값을 넣으면 NullPointerException 이 발생합니다.
String name = "John";
Optional<String> optionalName = Optional.of(name); // 정상 작동
System.out.println(optionalName); // Optional[John]
String nullName = null;
Optional<String> errorOptional = Optional.of(nullName); // NullPointerException 발생
Optional.ofNullable(value)
값이 null 일 수도 있고 아닐 수도 있을 때 사용합니다.
null 값이 들어오면 비어있는 Optional을 반환합니다.
null 값이 들어오면 Optional.empty를 반환합니다.
String name = "John";
Optional<String> optionalName = Optional.ofNullable(name); // 값 "John"을 감쌈
String nullName = null;
Optional<String> emptyOptional = Optional.ofNullable(nullName); // 비어있는 Optional 반환
Optional.empty()
비어있는 Optional 객체를 직접 생성합니다.
Optional<String> emptyOptional = Optional.empty();
Optional의 주요 메서드
isPresent()
값이 존재하는지 확인합니다.
값이 있으면 true, 없으면 false를 return 합니다.
Optional<String> optional = Optional.ofNullable("John");
if (optional.isPresent()) {
System.out.println("Value exists: " + optional.get());
} else {
System.out.println("Value is null.");
}
ifPresent()
값이 있을 때 특정 작업을 수행합니다.
Optional<String> optional = Optional.ofNullable("John");
// 값이 있을 때만 출력
optional.ifPresent(name -> System.out.println("Hello, " + name + "!"));
orElse()
값이 없을 때 기본 값을 제공합니다.
String name = null;
Optional<String> optional = Optional.ofNullable(name);
// 값이 없으면 "Default Name" 사용
String result = optional.orElse("Default Name");
System.out.println(result); // 출력: Default Name
orElseGet()
값이 없을 때 람다식으로 기본 값을 제공합니다.
orElse와 비슷하지만 좀 더 유연하고 필요에 따라 특정 작업을 추가할 수 있습니다.
String name = null;
Optional<String> optional = Optional.ofNullable(name);
// 값이 없으면 기본 값을 계산하여 반환
String result = optional.orElseGet(() -> "Generated Default Name");
System.out.println(result); // 출력: Generated Default Name
orElseThrow()
값이 없을 때 예외를 발생시킵니다.
String name = null;
Optional<String> optional = Optional.ofNullable(name);
// 값이 없으면 예외 던짐
String result = optional.orElseThrow(() -> new IllegalArgumentException("No value present"));
사용법 예시
기존에는 아래와 같이 null 검사를 한 후에 null 일 경우에는 새로운 객체를 생성해주어야 했습니다.
이러한 과정을 코드로 나타내면 다소 번잡해 보이는데, Optional <T>와 Lambda를 이용하면 해당 과정을 보다 간단하게 표현할 수 있습니다.
// Java8 이전
List<String> names = getNames();
List<String> tempNames = list != null ? list : new ArrayList<>();
// Java8 이후
List<String> nameList = Optional.ofNullable(getNames())
.orElseGet(() -> new ArrayList<>());
정리
Optional 은 null 또는 값을 감싸서 NPE로부터 부담을 줄이기 위해 등장한 Wrapper 클래스입니다. Optional 은 값을 Wrapping 하고 다시 풀고, null 일 경우에는 대체하는 함수를 호출하는 등의 오버헤드가 있으므로 잘못 사용하면 시스템 성능이 저하됩니다. 그렇기 때문에 메서드의 반환 값이 절대 null 이 아니라면 Optional 을 사용하지 않는 것이 좋습니다.
즉, Optional 은 메소드의 결과가 null 이 될 수 있으며, null에 의해 오류가 발생할 가능성이 매우 높을 대 반환값으로만 사용해야 합니다.
'Java' 카테고리의 다른 글
자바의 람다 표현식 (1) | 2024.12.26 |
---|---|
Java - Enum (1) | 2024.12.24 |
자바의 Generic (1) | 2024.12.19 |
자바의 오류처리: 예외(Exception) 와 트랜잭션 처리 (0) | 2024.12.18 |
자바의 toString 메서드 (0) | 2024.12.17 |