티스토리 뷰
Optional은 Java8에서 새로 추가된 API이다. 처음봤을때 매우 당황스런 놈이었다.
Java8에 새로 추가된 요소들중 람다식이니 함수형 인터페이스다 뭐다 하는 놈들중 하나가 Optional 이다.
현재까지 내가 이해한 내용은 이 값이 비어있는 상태로 반환될 수 있음을 표시하는 것이다.
추가로 Null체크하기가 좋고(이거는 사용방법을 더 찾아봐야 한다..), 소스를 명확하게 작성할 수 있다는게 강점인것 같다.
하지만 소스상으로 구현이 가능하다고 해서 마구잡이로 사용하면 안된다고 한다. (아니 그럼 안되게 만들던가)
내가 내린 결론은 Optional은 잘 알고 써야지 모르면 그냥 안쓰는게 낫다는 것이다.
잘 써보고 싶어서 스택오버플로우에 있던 내용 + 내가 이해한걸 대충 정리한다.
"이 값이 비어있는 상태로 반환될 수 있음" 을 설명하면..
| public String tempString (String test) {...} | public Optional<String> tempString (String test) {...} |
| 이걸 보는 개발자는 보통 String이 넘어올 거라고 생각하지 Null이 올거라곤 기대하지 않는다. | 하지만 메소드를 보면 빈 값이 올수도 있음을 "인지" 할 수 있다는 것이다. |
그리고 나와 비슷한 궁금증을 가진 사람이 있어 한글로 옮겨봤다. 결론은 1번처럼 쓰는게 좋다고 하더라.
심지어 답변자가 Oracle에서 일하는 JDK 개발자여서 더 신뢰가 가는 답변이었다.
답변 말투는 내 맘대로 각색했다.
질문 >
https://stackoverflow.com/questions/23454952/uses-for-optional
* Java8을 사용한지 6개월이 지났고 API가 변경된 것들이 꽤 즐거운데요, 하지만 Optional을 사용할 때만 자신감이 떨어지네요.
Null이 나오는 모든곳에 사용하고 싶어지지만, 어떨때는 전혀 쓰고싶지 않아요. 둘 사이에서 갈팡질팡 하게 되네요.
정작 사용하면서도 의문인게,
- 가독성이 좋은지도 모르겠고
- 정말로 Null에 안전한건지도 모르겠고
- 그저 오버헤드만 더 일으키는건 아닌지
확신이 서지 않아요. 다음 예제들 처럼 쓰는데 Optional이 언제 유용한건지 여러분의 의견이 궁금합니다.
1. null이 반환될수도 있는 public 메소드의 리턴타입으로 사용할때
public Optional<Foo> findFoo(String id);
2. null일수도 있는 파라미터로 사용될때
public Foo doSomething(String id, Optional<Bar> barOptional);
3. bean의 멤버로 사용될때
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
4. (일반적으로 이렇게 쓸려고 하진 않지만) 컬렉션에서 사용할때 입니다.
List<Optional<Foo>>
5. 추가로 컬렉션에서 filter()를 사용해 null이나 기타 값들을 제거할 수 있는데 더 좋은 용도가 있을까요?
답변 >
Optional은 반환값이 "없다"를 indicate(표시)하기 위해 설계되었습니다. 이걸 쓰면 끊기지 않는 유연한 메소드 호출이 가능합니다.
1. 1번케이스가 가장 알맞은 사용방법입니다.
IntStream.findFirst() 같은 절대 null일수가 없는것을 리턴하는게 더 좋은 방법입니다.
2. null 이 될수도 있는 파라미터로 사용해도 작동은 되지만 좀 어설픈 방법입니다.
String 과 두번째 String이 올수도 있는 메소드가 있다고 칩시다.
다음처럼 사용해도 됩니다.
foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());
차라리 Null을 던지는게 더 낫겠네요.
foo("bar", "baz");
foo("bar", null);
더 좋은 방법이 있습니다. 단일 파라미터를 받고 메소드 오버로딩을 사용하는 거죠.
foo("bar", "baz");
foo("bar");
Optional 용법에 제한은 없지만, 굳이 안써도 위 케이스처럼 쓰는게 제일 편합니다.
3번 4번
필드 변수나 데이터 구조에 써버리면 잘못 사용 된 API로 판단합니다.
첫번째로 위에 언급했던 대로 optional의 설계 철학에 위반되는 사항입니다.
두번째로 어떤값도 추가할 수 없습니다.
Optional에서 값이 없는걸 다루는 3가지 방법이 있는데 :
- 값을 대체하는 방법을 제공하거나
- 주어진 값을 대체하는 함수를 불러주거나
- 또는 예외를 던지는 방법입니다.
클래스의 필드 변수로 사용할거라면 변수 초기화 때 위의 3가지 방법을 쓰거나, 필드 값을 할당할때 이런 방법을 쓸겁니다.
List의 값으로 쓰고싶다면 그냥 값을 추가하지 않으면 됩니다. 굳이 이렇게 쓸 필요가 없습니다. (그냥 Null로 쓰거나 new로 초기화 하면 되지 않냐 이런 의미인듯)
하지만 이 중 누군가는 컬렉션에 Optional을 저장하는 예제를 들 수도 있겠지만, 이런건 피하는것이 가잫 좋습니다.
(굳이 Optional 꾸역꾸역 넣어가면서 소스 이상하게 쓰지말라는 소리 같다.)
그리고 4번같은 경우 List<Optional<Foo>>가 잘못되었다고 한거고,
반대로 Optional<List<Foo>>는 잘못된 방법이 아닌것 같더라. List가 Null일 수도 있으니깐...
이 답변을 본 이후로 아주 조오금 Optional이란 놈에 대해서 알게된거 같다.
특히 Null체크를 쉽게 해보고 싶은데 실전엔 잘 못써먹겠음. (Stream도 비슷한 이유로 잘 못쓰겠다)
좀 더 실패하고 예제를 찾아가면서 알아가야 할 API인것 같다.
언제 또 정리 할 수 있을까......
'개발' 카테고리의 다른 글
| Java Lombok 라이브러리 어노테이션 대강 정리 (0) | 2023.05.29 |
|---|---|
| 로컬 빌드 시간 48분 > 10분으로 줄였던 세팅 기록. (3) | 2023.04.08 |
| Java8 - Null 체크를 Optional로 대체하기 (2) | 2023.03.02 |
- Total
- Today
- Yesterday
- 탭 전환 단축키
- maven
- 복붙 쉽게
- hmx 랩터
- IntelliJ
- java
- JavaFX
- 복붙 이력
- Ditto프로그램
- gradle
- 키보드 윤활
- 커스텀키보드
- 복붙 히스토리
- 클립보드 대체
- intellij 같은 단어 선택
- 윈도우 클립보드
- geonworks
- 윈도우 단축키
- 기계식키보드 윤활
- 인텔리제이 커서 여러개
- 스위치 윤활
- 프로젝트 환경 구축
- 기계식 윤활
- 인텔리제이 멀티커서
- 인텔리제이 메이븐
- 믹틀란
- 기계식키보드
- 기계식키보드 스위치
- 지온웍스
- 단축키
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |