만족은 하되 안주하지는 말자

기록해야 기억한다

프로그래밍/JAVA

[Java] Optional 에 대해 알아보자 - 1

D36choi 2021. 3. 29. 09:53
728x90

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이 나올 수 있는 경우를 예외처리 해줘야 합니다.


https://www.baeldung.com/java-optional