2022. 2. 16. 22:52ㆍJAVA
Optional 타입의 객체에는 모든 타입의 참조변수를 담을 수 있다.
참조변수를 직접 담지 않고 Optional에 담는 이유는
1) Null을 직접 다루는 것은 NullPointerException의 위험이 존재한다. Optional을 이용하면 Null을 간접적으로 다룰 수 있다.
2) 위와 같은 이유로, Optional을 사용하지 않으면 Null 체크를 if문 등으로 해주어야 하는데, 이는 코드가 지저분하다.
Optional 객체 생성하기
String str = "abc";
Optional<String> opt = Optional.of(str);
Optional<String> opt2 = Optional.ofNullable(null); // 가능
Optional<String> opt2 = Optional.of(null); // NullPointerException 발생
값이 null일 가능성이 있는 경우, ofNullable 메서드를 이용해 Optional 객체로 생성해줄 수 있다.
Optional 객체로 저장한 값을 가져올때는
Optional<String> opt = Optional.of("abc");
String str1 = opt.get();
String str2 = opt.orElse("");
String str3 = opt.orElseGet(()->new String("abcd"));
단순히 get으로 뽑아오거나, null일 경우 alternative, 람다식을 반환하는 orElse(), orElseGet() 등을 활용 가능하다.
이런 Optional은 Stream과 자주 쓰이는데, Stream에서 값을 추출할때, Optional 타입으로 반환받는 경우가 많다.
Stream의 최종연산에 해당하는
stream().reduce()
stream().findAny()
등은 반환값이 Optional<T>이다.
22.10.20
Optional을 학습했다.
Brian Goetz가 스택오버플로우에서 Optional을 만든 의도에 대해 설명했는데, 메서드가 반환할 결과값이 ‘없음’을 명백하게 표현할 필요가 있는 곳에서 제한적으로 사용할 수 있는 메커니즘을 제공하는 것이 Optional을 만든 의도라고 한다.
Optional을 사용할 때 자주 등장하는 안티패턴을 잘 정리한 블로그가 있어 첨부한다.
눈여겨 본 부분은
2. orElse(new ...) 대신 orElseGet(() -> new ...)
이 부분이었는데, 휙! 보면
orElse() 메소드의 이름 때문에 Optional에 담긴 대상이 null인 경우에만 orElse( ... ) 부분이 실행될 것이라고 생각하기 쉽다.
하지만, null이든 아니든 orElse(...) 메소드는 실행이 되고 null이 아닌 경우에는 실행한 값이 그대로 버려진다.
당연한 것이, method1(method2()); 를 실행하면 method2가 먼저 실행된다는 것과 똑같다..
아무튼 orElse()를 사용할 때, 새로운 객체를 생성하거나 연산을 수행하는 경우라면 주의해야 할 것이다.
이런 사소한 것을 놓치면 큰 장애로 이어질 수 있다.
'JAVA' 카테고리의 다른 글
Java - Calculator 과제 회고 (0) | 2022.10.30 |
---|---|
Java 숫자야구 (0) | 2022.10.21 |
Collection과 Iterator (0) | 2022.10.20 |
JAVA 인터페이스 기능과 디폴트 메소드(Default Method) (0) | 2022.10.20 |
Java equals()와 hashCode() (0) | 2022.10.19 |