Optinal class 는 자바 8에서 도입된 주요 기술 중 하나입니다.
이 클래스의 목적은 null 대신에 optional한 (있거나 없을 수 있는) 값을
표현하기 위한 해결책을 제공하는 것입니다.
기본 Optional 객체 생성법
// 기본 생성법. 대상이 Null 이 될 수 없을 떄는
@Test
public void NonNullWhenCreated() {
String fruit = 'apple';
Optional<String> opt = Optional.of(fruit);
assertTrue(opt.isPresent());
}
기본적으로 Optinonal.of() 의 파라미터는 null 이 될수 없습니다.
하지만 ofNullable() 은 다릅니다.
// 대상이 Null 일 수 있는 경우
@Test
public void NullableWhenCreated() {
String fruit = null;
Optional<String> opt = Optional.ofNullable(fruit);
assertFalse(opt.isPresent());
}
isPresent()
포장된 값이 null 이 아니면 True 를 반납합니다.
isEmpty()
java 11 에서는 isEmpty() 로 null 인 경우 true 를 얻을 수 있습니다.
ifPresent() 를 활용한 조건문 실행
ifPresent() 를 활용하면 포장된 값이 null 이 아닐 경우 실행되는, if문 보다 훨씬 간결한
코드를 작성 가능하고, 만약 내가 null check 를 하지 않는 경우가 없게끔 만들어 줍니다.
만약 null check 를 놓친다면 NullPonterException 이 런타임 중에 던져지므로 프로그램에 큰 문제가 됩니다.
if(name != null) {
log.info(name.length());
}
->
@Test
public void ifPresentTest() {
Optional<String> opt = Optional.of("apple");
opt.ifPresent(name -> log.info(name.length()));
}
Default value with orElse()
orElse() 메서드를 활용하면 default 값을 설정할 수 있습니다.
만약 Optional 포장값이 null이라면 orElse 의 파라미터로 세팅합니다.
@Test
public void whenOrElseWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("choi");
assertEquals("choi",name);
}
@Test
public void whenOrElseGetWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseGet(() -> "john");
assertEquals("john", name);
}
orElse 와 같아보이지만 다른 점은, orElse 는 밸류리턴이라면 이것은 함수형 인터페이스를 활용해서 값을 invoke 한다는 차이가 있습니다.
더 큰 차이점은?
성능에 큰 차이가 있습니다.
- orElseGet() 은 포장값이 Null 이 아닌 경우 호출되지 않는다.
- orElse() 는 포장값이 Null 이 아닌 경우에도 default 객체를 생성한다.
만약 매우 자주 호출하는 코드에 orElse() 가 들어가고, 매번 객체를 생성하게 된다면 쓰레기값이 생기는건 자명할 것입니다.
orElseThrow() 를 활용한 예외 처리
@Test(expected = IllegalArgumentException.class)
public void ExceptionTestWithOptional() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(
IllegalArgumentException::new);
}
어떤 값이 들어갈지 애매모호한 변수에 대해서 예외처리를 간단하게 할 수 있습니다.
get() 을 활용한 값의 반환
포장값을 Optional 객체에서 꺼내 사용하기 위해서는 get() 을 활용합니다.
@Test
public void givenOptional_whenGetsValue_thenCorrect() {
Optional<String> opt = Optional.of("apple");
String fruit = opt.get();
Assertions.assertThat("apple").isEqualTo(fruit);
}
주의점 !
Get() 은 오로지 포장값이 null 이 아닐때만 사용할 수 있습니다.
만약 null 인 포장값을 get() 하려 하면 NoSuchElementException 이 던져지게 됩니다.
Optional 의 목표와 상반되는 메서드이기때문에 어떻게 보면 갸우뚱하게 되는데요.
우리가 직접 null이 나올 수 있는 경우를 예외처리 해줘야 합니다.
'프로그래밍 > JAVA' 카테고리의 다른 글
[Java] custom Object 리스트를 Map 리스트로 변환하기 (object to map using stream) (0) | 2021.04.22 |
---|---|
[Java] Optional 에 대해 알아보자 - 2 (0) | 2021.04.21 |
[Java] 내가 만든 클래스 객체 배열 정렬하기 (comparable, comparator, comparing) (0) | 2021.02.14 |
[Java] 단위테스트: System.out.println() 과 Scanner.in 이 들어간 코드를 어떻게 테스트할까? (0) | 2021.01.19 |
[Java] JVM, JRE, JDK 한줄 정리 (0) | 2020.10.30 |