-
자바의 Optional 클래스CS/JAVA 2025. 2. 16. 01:34
자바 프로그래밍에서는, NullPointerException 예외가 자주 발생하는데요, 이 예외는 null값을 역참조하기 때문입니다.
Optional 클래스는 이런 문제를 해결하기 위해 등장했습니다.
Optional은 값이 있을 수도 있고 없을 수도 있는 객체를 감싸는 래퍼 클래스입니다. 이를 통해 명시적으로 해당 값이 null일 수 있음을 표현할 수 있으며, NullPointerException을 방지할 수 있는 API를 제공합니다.
예를들어, null값인 String에서 length()를 호출하면 NullPointerException이 발생합니다.
하지만 Optional로 감쌀 경우 NullPointerException의 발생을 방지할 수 있습니다.
String value = null; System.out.println(value.length()); // NullPointerException 발생 Optional<String> optionalValue = Optional.ofNullable(null); System.out.println(optionalValue.map(String::length).orElse(0)); // 0 출력저의 경우에 Optinal을 가장 많이 사용한 예시는 JPA로 데이터를 조회해올 때입니다.
Member 객체를 조회하고자 할 때,
다음과 같이 findByName 메서드의 반환값을 Member객체로 한다면, 조회한 name을 가진 Member가 없을 경우 예외가 터집니다.
public interface MemberRepository extends JpaRepository<Member, Long> { Member findByName(String name); } @Service @RequiredArgsConstructor public class Service{ private final MemberRepository memberRepository; Member getMember(String name){ Member member = memberRepository.findByName(name);//조회된 데이터가 없으면 예외 발생 return member; } }하지만 findByName 메서드의 반환값을 Optinal로 한다면, 조회한 name을 가진 Member가 없어도 예외가 터지지 않습니다.
Optinal은 null일 경우 ~~ 때문입니다.
public interface MemberRepository extends JpaRepository<Member, Long> { Optional<Member> findByName(String name); } @Service @RequiredArgsConstructor public class MemberService{ private final MemberRepository memberRepository; Member getMember(String name){ Optional<Member> optional = memberRepository.findByName(name); //조회된 데이터가 없어도 예외가 발생하지 않음 return optional.orElse(null);// 값이 있을경우 Member 반환, 없으면 null 반환 } }Optional 객체 생성하기
Optional 객체를 생성하는 방법은 여러가지입니다.
1. Optional.empty()
명시적으로 값이 비어있는 Optional 객체를 표현할 때 사용합니다.
Optional emptyOptional = Optional.empty();2. Optional.of()
null이 아닌 값을 갖는 Optional 객체를 생성합니다. 만약 value가 null이라면 NullPointerException이 발생합니다.
Optional optional1 = Optional.of("value"); Optional optional2 = Optional.of(null); //NullPointerException 발생3. Optional.ofNullable()
값이 null일 수도 있는 경우에 사용됩니다. value가 null이면 비어있는 Optional 객체를, 그렇지 않으면 해당 값을 갖는 Optional 객체를 생성합니다.
Optional nullableOptional = Optional.ofNullable("value");Optional의 주요 메서드 - 값 가져오기
1. get()
get() 메서드는 Optional에 있는 값을 바로 가져오는 메서드입니다. 만약 Null인 경우 NPE가 발생하게 됩니다.
Optional<String> optional = Optional.of("value"); System.out.println(optional.get());2. isPresent(), isEmpty()
isPresent() 메서드는 값이 Null이 아니면 true를 Null이면 false를 리턴하고, isEmpty()는 반대로 Null이면 true를 아니면 false를 리턴하는 메서드입니다.
Optional<String> optional = Optional.of("value"); if(optional.isPresent()){ System.out.println(optional.get()); } if(optional.isEmpty()){ System.out.println("is empty"); }3. ifPresent()
Optional 객체에 값이 존재하면 람다식(Consumer 함수형 인터페이스)을 실행하고, 값이 없으면 아무 일도 하지 않는 메서드입니다.
Optional<String> optional = Optional.of("value"); optional.ifPresent((value) -> System.out.println("값이 존재합니다: " + value));Optional의 주요 메서드 - 종료 연산
1. orElse()
Optional 객체에 값이 존재하면 그 값을 반환하고, 값이 없으면 미리 지정한 기본값(other)을 반환하는 메서드입니다.
Optional<String> optional1 = Optional.of("value"); Optional<String> optional2 = Optional.ofNullable(null); System.out.println(optional1.orElse("defualt")); // "value" 출력 System.out.println(optional2.orElse("defualt")); // "defualt" 출력2. orElseGet()
Optional 객체에 값이 존재하면 그 값을 반환하고, 값이 없으면 람다식(Supplier)을 실행하여 동적으로 값을 생성하는 메서드입니다.
Optional<String> optional = Optional.ofNullable(null); System.out.println( optional.orElseGet(() -> new String("Default Value"))); // "Default Value" 출력3. orElseThrow()
Optional 객체에 값이 존재하면 반환하고, 없으면 예외를 발생시키는 메서드입니다.
Optional<String> optional = Optional.ofNullable(null); String result = optional.orElseThrow(() -> new RuntimeException("값이 없습니다!")); //RuntimeException 발생 System.out.println(result); // 실행되지 않음Optional의 주요 메서드 - 중간 연산
1. map(Function)
Optional 내부의 값을 변환할 때 사용합니다.
값이 존재하면 변환을 적용한 새로운 Optional을 반환하고, 값이 없으면 그대로 Optional.empty()를 반환합니다.
Optional<String> optional = Optional.of("hello"); String string = optional.map(String::toUpperCase).orElse("empty"); System.out.println(string); //"HELLO" 출력2. filter()
Optional 내부 값이 특정 조건을 만족하면 유지하고, 그렇지 않으면 Optional.empty()를 반환하는 메서드입니다.
Optional<String> optional = Optional.of("hello"); Optional<String> result1 = optional.filter(value -> value.equals("hello")); // "hello"이면 유지, 아니면 Optional.empty() Optional<String> result2 = optional.filter(value -> value.equals("world")); // "world"이면 유지, 아니면 Optional.empty() System.out.println(result1.orElse("is Empty")); //"hello" 출력 System.out.println(result2.orElse("is Empty")); //"is Empty" 출력3. flatMap(Function)
Optional<Optional<T>> 같은 중첩된 Optional을 Optional<T>로 변환하는 메서드입니다.
내부 값이 Optional이라면 중첩을 풀어주고, 값을 없으면 그대로 Optional.empty()를 반환합니다.
Optional<Optional<String>> optional = Optional.of(Optional.of("hello")); Optional<String> result = optional.flatMap(opt -> opt); System.out.println(result); //"hello" 출력class Member { private Optional<String> name; public Optional<String> getName() { return name; } } public class FlatMapExample { public static void main(String[] args) { Member = new Member("Alice"); Optional<Member> optionalMember = Optional.of(member); Optional<String> result = optionalMember.flatMap(Member::getName); System.out.println(result); //"Alice" 출력 } }'CS > JAVA' 카테고리의 다른 글
Java Template Engine (1) 2025.03.31 JVM(Java Virtual Machine) (4) 2024.09.02 JAVA - Tomcat, Servlet 으로 클라이언트 요청받기 (2) 2024.06.17 JAVA - JDBC 사용해 db서버와 데이터 요청/응답 받기 (1) 2024.06.05 JAVA - 오버로딩, 오버라이딩 (3) 2024.06.04