-
[Java] Optional이란?Java 2022. 2. 11. 00:01
Optional이란?
Java 8에서 최초로 도입되었습니다.
'T' 타입의 객체를 포장해 주는 래퍼 클래스로 모든 타입의 참조 변수를 저장할 수 있습니다.
Optional은 "값이 존재할 수도 있지만 안 할 수도 있는 객체" 즉, "null이 될 수도 있는 객체"를 포장해주는 래퍼클래스입니다.
public final classOptional<T>{ private final T value; }
래퍼 클래스란?
만약 메서드가 매개변수를 객체 형태로 받을 경우 기본 타입을 객체화하여 매개변수로 전달할 때 사용하는 클래스로 자세한 부분은 아래 링크를 참조하시면 좋을 것 같습니다.
Optional을 사용하는 이유
null을 간접적으로 다루기 위해 등장하게 됩니다.
null을 직접 다루는 것은 NullpointerException을 발생시킬 수 있어서 위험합니다.
또한 null 그것을 방지하기 위해 검증을 하기 위해서는 if문이 필요하므로 코드가 지저분해집니다.
명시적으로 해당 변수가 null일 수도 있다는 가능성을 표현할 수 있습니다.
NullpointerException에 대해 알아보겠습니다.
String str; //초기화 하지 않아서 null로 초기화됨 str.indexOf(1); //str이 null이기 때문에 NullPointerException에러가 발생하게 될 것임. //컴파일러가 해당 참조변수는 아직 초기화 되지 않았다는 메시지 표출 public void doSomething(SomeObject obj){ obj.myMethod(); } //만약 obj의 인수로 null이 넘어오게 되면 NullPointerException이 발생하게 됩니다. public void doSomething(SomeObject obj){ if(obj == null){ //obj가 null일 때 로직 } else{ //obj를 이용한 로직 } }
변수를 초기화하지 않은 경우에는 컴파일러가 초기화되지 않았다고 에러가 발생합니다.
변수를 String str=null; 로 초기화한 후 str.indexOf(1)을 진행한다면 NullPointerException 에러가 발생하게 됩니다.
또한 doSomething 함수의 obj 함수 인자로 null값이 전달될 경우에 NullPointerException 에러가 발생하게 됩니다.
또한 에러를 처리하기 위해 if문을 사용하여 null을 처리해주어야 하므로 코드가 지저분해집니다.
Optional 메서드
String str = "abc"; Optional<String> optVal = Optional.of(str); Optional<String> optVal = Optional.of(null); //NullPointerException발생 Optional<String> optVal = Optional.ofNullable(null); //OK Optional<String> optVal = null; //null로 초기화는 바람직하지 않음 Optional<String> optVal = Optional.empty(); //빈 객체로 초기화
Optional에는 여러 메서드가 존재합니다.
Optional.empty() : 비어있는 Optional 객체를 가져온다.
Optiona.of(T value) : null이 아닌 값을 담은 Optional 객체를 생성한다. 이 경우 null이 들어오면 NullPointerException이 발생한다.
Optional.ofNullable(T value) : 값이 null일 수도 아닐 수도 있는 객체를 생성한다.
Optional<String> optVal = Optional.of("abc"); String str1 = optVal.get(); //optVal에 저장된 값을 반환, null이면 예외발생 String str2 = optVal.orElse("");//optVal에 지정된 값이 null일 때는 ""를 반환 String str3 = optVal.orElseGet(String::new)//람다식 사용가능() -> new String() String str4 = optVal.orElseThrow(NullPointerException::new);//null이면 예외 발생 //get을 try-catch와 사용 try{ str = opt.get(); }catch(Exception e){ str =""; } //orElse 메소드 사용시 str = opt.orElse("");
Optional 값에 접근
1. get()
2. orElse(T other)
3. orElseGet(Supplicer <? Extends T> other)
4. orElseThrow()
5. isPresent()
Optional의 잘못된 사용
//Optional 사용 public String findStationName(Optional<Station> optStation) { if (optStation.isPresent()) { return optStation.get().getName(); } return new Station("존재하지 않는 역").getName(); } //Optional 사용x public String findStationName(Station station) { if (Objects.nonNull(station)) { return station.getName(); } return new Station("존재하지 않는 역").getName(); }
위 코드들은 무엇이 다를까요? Optional을 사용해서 좋아진 게 있을까요?
Optional 적용 후에는 null 체크를 하지 않아야 합니다.
Optional을 사용하는 이유는 null을 직접 처리하지 않고 Optional 클래스에 위임하기 위해서입니다.
올바른 Optional 사용법
public String findStationName(Optional<Station> optStation) { return optStation.orElse(new Station("존재하지 않는 역")).getName(); }
Optional의 장점
명시적으로 변수에 대한 null 가능성을 표현할 수 있다.
null 체크를 직접 하지 않아도 된다.
Null Point Exception이 발생할 가능성이 있는 값을 직접 다룰 필요가 없다.
Optional의 단점
Wrapper 클래스이기 때문에 두 개의 참조를 가지므로 생성 비용이 비싸다.
직렬화 불가능하기 때문에 클래스의 인스턴스 필드로 사용하면 안 된다.(값을 반환하는 용도로 사용해야 한다.)
출처
자바의 정석
https://www.youtube.com/watch?v=W_kPjiTF9RI
https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/Optional.html
https://yangbox.tistory.com/49
https://www.daleseo.com/java8-optional-after/
https://tecoble.techcourse.co.kr/post/2021-06-20-optional-vs-null/
'Java' 카테고리의 다른 글
[Java] 이클립스 글자 안 보일 때 해결 방법(이클립스 흰 화면 출력 시 해결 방법) (0) 2022.02.26 [Java] DTO, DAO, VO란? (0) 2022.02.19 [Java] 스트림의 최종연산 (0) 2022.02.10 [Java] 스트림의 중간연산 (0) 2022.02.09 [Java] Math.max() vs 삼항연산자 (0) 2022.02.07