값을 포함하거나 포함하지 않을수 있는 객체
`null`값을 직접 반환하는 대신 `Optional`객체를 반환하여 값의 유무를 명시적으로 처리하도록 함
1. Optional 생성
1.1. Optional.of()
- `null`이 아닌 값을 가진 객체를 생성
- `null`값을 전달하면 NullPointerException이 발생
Optional<String> opt = Optional.of("Hello");
1.2. Optional.ofNullable()
- `null`값을 허용하며, 값이 `null`이면 비어있는 객체를 생성
Optional<String> opt = Optional.ofNullable(null);
// opt 는 Optional.empty();
1.3. Optional.empty()
- 값이 비어있는 객체 생성
2. 메서드
2.1. isPresent()
- 값이 존재하면 `true` 존재하지않으면 `false`를 반환
Optional<String> opt = Optional.of("Hello");
System.out.println(opt.isPresent()); // true
2.2. ifPresent()
- 값이 존재하면 주어진 작업을 수행
Optional<String> opt = Optional.of("Hello");
opt.ifPresent(value -> System.out.println(value)); // Hello
2.3. get()
- 값이 존재하면 값을 반환
- 없으면 `NoSuchElementException`이 발생하므로 주의
Optional<String> opt = Optional.of("Hello");
System.out.println(opt.get()); // Hello
2.4. orElse()
- 값이 있으면 값을 반환, 없으면 기본값을 반환
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse("Default")); // Default
2.5. orElseGet()
- 값이 있으면 값을 반환, 없으면 람다표현식이나 메서드 참조로 기본값을 생성하여 반환
Optional<String> opt = Optional.empty();
System.out.println(opt.orElseGet(() -> "Generated Default")); // Generated Default
2.6. orElseThrow()
- 값이 있으면 반환, 없으면 예외를 발생
Optional<String> opt = Optional.empty();
opt.orElseThrow(() -> new IllegalStateException("값이 없습니다."));
2.7. filter()
- 값이 존재하고 주어진 조건을 만족하면 값을 포함한 `Optional`을 반환하고, 그렇지않으면 빈 `Optional`을 반환
Optional<String> opt = Optional.of("Hello");
Optional<String> filtered = opt.filter(value -> value.startsWith("H"));
System.out.println(filtered.isPresent()); // true
2.8. map()
- 값을 변환하여 새 객체로 반환
- 값이 없으면 빈 객체 반환
Optional<String> opt = Optional.of("Hello");
Optional<Integer> lengthOpt = opt.map(String::length);
System.out.println(lengthOpt.get()); // 5
2.9. flatMap()
- 객체를 반환하는 매핑함수에 사용됨
- map과 달리 중첩된 객체를 한단계로 펼침
Optional<String> opt = Optional.of("Hello");
Optional<String> upperCaseOpt = opt.flatMap(value -> Optional.of(value.toUpperCase()));
System.out.println(upperCaseOpt.get()); // HELLO
3. Optional 예제
3.1. NullPointerException 방지
public String getName(Person person) {
return Optional.ofNullable(person)
.map(Person::getName)
.orElse("Unknown");
}
3.2. 데이터베이스 조회 예제
public Optional<User> findUserById(int id) {
User user = database.queryUser(id); // null 가능
return Optional.ofNullable(user);
}
Optional<User> userOpt = findUserById(123);
userOpt.ifPresent(user -> System.out.println(user.getName()));
3.3. 조건에 따라 값 처리
Optional<String> opt = Optional.of("Java Optional");
opt.filter(value -> value.contains("Java"))
.ifPresent(System.out::println); // Java Optional
4. Optional 장점
- 명시적인 null처리 - 메서드 반환값에서 값이 없음을 명시적으로 알 수 있다
- NullPointerException 방지 - null을 직접 다루지 않아 NPE 발생 가능성이 줄어든다
- 가독성 향상 - 값이 없을 경우를 처리하는 코드가 더 명확해진다
- 함수형 프로그래밍 스타일 - 간결하고 선언적인 코드 작성 가능하다
5. 주의사항
- 필드에 사용 금지
- 값이 없는 상태로 get() 금지 - `isPresent`로 확인후 사용하거나 `orElse`사용
- 기본자료형 Optional - `OptionalInt`, `OptionalDouble`등의 클래스 사용이 권장
6. Optional의 대안
- null 자체를 잘 관리한다면 Optional을 사용할 필요는 없다
- 값이 있을수도 있고, 없을수도 있는 상황에서만 사용
출처 : ChatGPT
'BE > Java' 카테고리의 다른 글
[Java] 스트림 (1) | 2024.12.09 |
---|---|
[Java] Map (0) | 2024.12.07 |
[Java] List (1) | 2024.12.05 |
[Java] 컬렉션 (0) | 2024.12.04 |
[Java] 래퍼 클래스 (0) | 2024.12.03 |