📍 Optional
Optional 클래스는 'T'타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)이다.(null이 올 수 있는 값을 감싸는 Wrapper 클래스이다.)
Optional 객체를 사용하면 예상치 못한 NullPointerException
예외를 제공되는 메소드로 간단히 회피할 수 있다.
객체 생성
of() 메소드나 ofNullable() 메소드를 사용하여 Optional 객체를 생성할 수 있다.
객체가 null이 될 가능성이 있다면 ofNullable()을 사용하는 것이 좋다.
그 외의 메소드
- isPresent() : Optional 객체에 저장된 값에 접근.
- get() : Optional 객체에 저장된 값을 반환함.
- orElse() : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환함. (Optional 안의 값이 null이든 아니든 항상 호출됨.)
- orElseGet() : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결과값을 반환함. (Optional 안의 값이 null인 경우에만 호출됨.)
- orElseThrow() : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생시킴.
주의할 점
NullPointerException
대신 NoSuchElementException
가 발생함
Optional 객체에 저장된 값이 null이면 NoSuchElementException
이 발생한다. 값의 존재 여부를 판단한 후 접근해야 한다.
- 직렬화
Optional은 직렬화를 지원하지 않기 때문에 캐시나 메세지큐 등과 연동할 때 문제가 발생할 수 있다.
- 코드의 가독성을 떨어뜨림
Optional을 올바르게 사용하지 않으면 불필요한 코드가 증가해 가독성이 떨어질 수 있다.
- 시간적, 공간적 비용(또는 오버헤드)이 증가함
- 시간적 비용 : Optional 객체를 통해 접근해야 하므로 접근 비용이 증가한다.
- 공간적 비용 : Optional 객체를 위한 추가 메모리가 할당된다.
올바른 사용법
- Optional 변수에 Null을 할당하지 않는다.
- 값이 없을 때 Optional.orElseX()로 기본 값을 반환한다.
가급적이면 isPresent()로 검사하고 get()으로 값을 꺼내기 보다는 orElseGet 등을 활용해 처리하도록 하자.
- 단순히 값을 얻으려는 목적으로만 Optional을 사용하지 않는다.
- 생성자, 수정자, 메소드 파라미터 등으로 Optional을 넘기지 않는다.
- Collection의 경우 굳이 Optional을 사용할 필요 없다.
- 반환 타입으로만 사용한다❗️
=> Optional은 반환 타입으로 에러가 발생할 수 있는 경우에 결과가 없음을 드러내기 위해 만들어 진 것이다. 즉, Null을 반환하는 것 보다 값의 유무를 나타내는 객체를 반환하는 것이 합리적이므로 반환 타입으로만 사용되어야 한다!
Ref.
https://mangkyu.tistory.com/70