자바생
728x90

글을 쓰게 된 이유

 

체스 미션을 하면서 “Optional을 메서드의 파라미터로 넣는 것은 안티패턴이다.”라는 리뷰를 받았습니다.

처음에 stackoverflow를 보고 이해되질 않았습니다.

파라미터로 넣든, Optional 을 리턴하든 똑같은 거 아닌가?

 

스택오버플로우에 채택된 답을 보면 아래와 같습니다.

 

  1. Using Optional parameters causing conditional logic inside the methods is literally contra-productive.
  2. Needing to pack an argument in an Optional, is suboptimal for the compiler, and does an unnecessary wrapping.
  3. In comparison to nullable parameters Optional is more costly.
  4. The risk of someone passing the Optional as null in actual parameters.

메서드 내부에서 조건부 논리를 유발, 불필요한 래핑 수행, Optional 이 비용이 더 많이 든다 등은 Optional 을 파라미터로 넣어서가 문제가 아닌 단지 Optional 의 단점이라고 생각합니다.

 

마지막인 “파라미터에 누군가가 null 로 전달할 위험”이 있다는 게 가장 큰 문제입니다.

 

이게 왜 위험한지는 Optional 이 등장하게 된 배경부터 알아보겠습니다.

 

Optional은 왜 나왔을까?

 

Optional 은 Java 1.8 부터 나온 기능으로 왜 나왔는지는 API Note를 보겠습니다.

 

Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.

 

“결과 없음”을 명시적으로 표현해야하고, null 을 사용하면 오류가 발생할 가능성이 있는 메서드 반환 유형으로 사용하기 위함입니다. 유형이 Optional인 변수는 그 자체가 null 이 되어서는 안 되며, 항상 Optional 인스턴스를 가리켜야 합니다.

 

즉, 결과가 없을 수도 있다는 것을 나타내기 위해(nullable), null을 안전하게 사용하기 위해서(nullsafe) 만들어진 ‘컨테이너 객체’ 입니다.

그리고 “메서드 반환 유형”으로 사용, “Optional인 변수는 그 자체가 null 이 되면 안 된다”라고 작성돼 있습니다.

 

메서드 파라미터로 Optional 을 사용하게 되면 위 두 가지 모두 위배할 수 있습니다.

 

class B {

    public void parameterOptional(final Optional<Box> box) {

        // if(box == null)

        box.ifPresentOrElse(
                it -> System.out.println(it.fruit()),
                NoSuchElementException::new
        );
    }
}

@Test
void test_optional() throws Exception {
    B b = new B();

    Assertions.assertThatThrownBy(() -> b.parameterOptional(null))
              .isInstanceOf(NullPointerException.class);
}

테스트를 해보면 NPE가 발생하는 것을 알 수 있습니다.

 

코드를 보면 뭔가 찜찜하지 않으신가요?

우리는 대부분 Optional 을 사용할 때, 주석과 같이 null 체크를 할까요? 하지 않습니다.

이미 Optional 객체를 호출하면서 null 이면 A 행위, null 이 아니면 B 행위를 합니다. 코드와 같이 ifPresentOrElse와 같은 메서드를 사용하면서 말이죠.

 

만약 파라미터 자체에 null 이 들어왔다?

그러면 바로 NPE 터지는 거죠,,

 

결론

위와 같은 이유로 인해서 Optional을 파라미터에 넣는 것은 안티패턴이라고 합니다.

처음에는 스택오버플로우를 보고 이해 못 했습니다.

 

Optional 자체를 null 로 보내는 것이 아닌, Optional.isEmpty() 와 같이 Optional 안에 null 이 있는 상황만 생각했습니다. 그래서 “파라미터로 사용, 리턴을 하던 똑같지 않나” 라고 생각했습니다.

 

Optional 에 대한 개발자들의 생각, 등장배경과 생각하니 Optional 자체에 null 이 들어가면 매우 위험한 상황이 생길 수 있기 때문에, 왜 안티패턴이라고 불리는지 알 수 있었습니다.

 

REFERENCES

 

stackoverflow

java doc

728x90

'Java' 카테고리의 다른 글

try-with-resources 는 왜 사용해야할까?  (0) 2023.03.28
unmodifiableList & copyOf & 방어적 복사  (0) 2023.02.21
Generic & Wildcard  (0) 2022.12.29
Generic in Java  (2) 2022.12.17
JDK ? JRE ?  (0) 2022.09.15
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그