IT박스

null을 반환 할 수있는 모든 메서드에 대해 Java8 / Guava Optional을 사용해야합니까?

itboxs 2020. 12. 5. 09:25
반응형

null을 반환 할 수있는 모든 메서드에 대해 Java8 / Guava Optional을 사용해야합니까?


선택 사항은 nullable 개체를 나타내는 데 사용됩니다.이 클래스의 일부 용도는 다음과 같습니다.

  1. 메서드 반환 유형으로서,
    값을 사용할 수 없음 나타 내기 위해 null을 반환하는 대신
  2. "알 수 없음"(예 :지도에 없음)과 "값이없는 것으로 알려짐"(지도에 표시되며 값은
    Optional.absent ()) 구분
  3. null을 지원하지 않는 컬렉션의 저장소에 대한 nullable 참조를 래핑하려면 (먼저 고려해야하는 몇 가지 다른 접근 방식이 있지만)

첫 번째 경우 모든 nullable 반환 메서드에서 Optional을 반환해야합니까?


그렇다면 옵션의 문제점은 무엇입니까?

우리가 직면하는 질문은 JDK 8 Optional 객체가 널 참조를 제거 할 것인가입니다. 그리고 대답은 단호하게 아니오입니다! 따라서 비방하는 사람들은 즉시 그 가치에 의문을 제기합니다. 그러면 우리가 다른 방법으로 할 수없는 것이 무엇에 유익할까요?

널 참조의 개념이 없었던 SML 또는 Haskell과 같은 기능적 언어와 달리 Java에서는 역사적으로 존재했던 널 참조를 단순히 제거 할 수 없습니다. 이것은 계속 존재할 것이며, 적절한 용도를 가지고있을 것입니다 (예제를 언급하자면 : 3 값 논리 ).

Optional 클래스의 의도는 모든 단일 nullable 참조를 대체하는 것이지, 메서드의 서명을 읽는 것만으로 선택적 값을 기대할 수 있는지 여부를 알 수있는보다 강력한 API를 만드는 데 도움이되는 것인지 의심합니다. 프로그래머가 그에 따라이 값을 사용하도록합니다. 그러나 궁극적으로 Optional은 다른 참조 일 뿐이며 해당 언어의 다른 모든 참조와 동일한 약점을 따릅니다 (예 : null Optional을 반환 할 수 있음). Optional이 하루를 저장하지 않을 것이 분명합니다.

이러한 선택적 객체가 어떻게 사용되어야하는지 또는 Java에서 가치가 있는지 여부 는 프로젝트 람다 메일 링리스트에서 열띤 논쟁 의 문제였습니다 . 비방하는 사람들로부터 우리는 다음과 같은 흥미로운 주장을 듣습니다.

  • 다른 대안이 존재한다는 사실 (예 : IntelliJ 및 Eclipse IDE와 같은 IDES 는 null 가능성의 정적 분석을위한 독점적 주석 집합 , @Nullable 및 @NonNull과 같은 주석이 있는 JSR-305 )을 지원합니다.
  • 어떤 사람들은 SML이나 Haskell과 같은 기능적 프로그래밍 언어 (예 : 패턴 매칭)에 존재하는 많은 기능이 부족하기 때문에 Java에서는 완전히 불가능한 기능적 세계 에서처럼 사용할 수 있기를 원합니다 .
  • 다른 사람들은 이 관용구 (예 : 계속해서 null을 반환하는 List.get (Object))를 사용하기 위해 기존 코드개조 하는 것이 불가능하다고 주장합니다 .
  • 그리고 일부는 선택적 값에 대한 언어 지원이 부족하여 선택적 값 이 API에서 일관되지 않게 사용될 수있는 잠재적 시나리오가 생성된다는 사실에 대해 불평합니다. 이로 인해 나머지 Java API와 매우 유사한 비 호환성이 생성됩니다. 새로운 옵션 클래스를 사용하도록 개조 할 수 없습니다. 이것은 당신의 질문입니다. Ceylon 또는 Kotlin과 같은 선택적 유형을 지원하는 언어에서는 이것에 의문을 제기하지 않을 것입니다.
  • 매력적인 인수는 프로그래머가 선택적 개체에서 get 메서드를 호출하면 비어 있으면 NoSuchElementException이 발생한다는 것입니다. 이는 다른 예외를 제외하고는 null과 거의 동일한 문제입니다.

따라서 Optional의 이점은 실제로 의문의 여지가 있으며 가독성을 높이고 공용 인터페이스 계약을 시행하는 데 제약이있을 수 있습니다.

이 선택적 기능 관용구를 채택하면 코드가 더 안전 해지고 null 역 참조 문제에 대한 프롬프트가 줄어들고 결과적으로 더 강력하고 오류 발생 가능성이 낮아질 것입니다. 물론 이것은 완벽한 해결책은 아닙니다. 왜냐하면 결국 Optional 참조는 null 참조로 잘못 설정 될 수 있기 때문입니다.하지만 저는 프로그래머가 옵션 객체가 예상되는 곳에 null 참조를 전달하지 않는 규칙을 고수 할 것으로 예상합니다. 오늘 우리는 컬렉션 또는 배열이 예상되는 곳에 null 참조를 전달하지 않는 좋은 방법을 고려합니다.이 경우 올바른 방법은 빈 배열 또는 컬렉션을 전달하는 것입니다. 여기서 요점은 이제 API에 주어진 참조에 대해 할당 할 값이 없을 수 있으며 사용자가이를 확인하도록 API에 의해 강제된다는 것을 명시하는 데 사용할 수있는 메커니즘이 API에 있다는 것입니다.

선택적 개체 사용에 대한 Google Guava의 기사 인용 :

“null에 이름을 부여하여 가독성이 증가하는 것 외에도 Optional의 가장 큰 장점은 바보 방지 기능입니다. 프로그램이 컴파일되기를 원한다면 부재 사례에 대해 적극적으로 생각해야합니다. 선택 사항을 적극적으로 풀고 해당 사례를 해결해야하기 때문입니다.”

따라서 Optional을 사용하여 얼마나 멀리 가고 싶은지 선택하는 것은 모든 API 디자이너에게 달려 있다고 생각합니다.

Stephen Colebourne 및 Brian Goetz와 같은 일부 영향력있는 개발자는 선택 사항의 적절한 사용에 대한 몇 가지 흥미로운 기사를 최근에 발표했습니다. 특히 다음과 같은 것이 유용하다는 것을 알았습니다.


관찰하자면 애플리케이션을 설계 할 때 고려해야 할 가장 중요한 측면 중 하나는 "null 문제"를 처리하는 방법을 결정하는 것입니다. 이 점에서 첫 번째 단계는 가능한 null의 "소스"를 식별하는 것입니다. 예를 들어, 프로젝트에 사용 된 데이터베이스 또는 외부 라이브러리입니다. 다음 단계는 문제를 '포함'하는 것입니다. 즉, 문제가있는 코드를 랩핑 (선택 사항 사용)하여 의심하지 않는 코드가 NPE를 트리거 할 수있는 시스템 전체에서 null 전파를 차단하는 것입니다.
귀하의 질문에 답하기 위해서는 상황에 따라 다릅니다 ... 대부분의 경우 값이없는 많은 작업을 생성하기 때문에 불필요하다고 말하고 싶습니다 (예를 들어, 클래스 내에서 다른 개인 메서드를 호출하는 메서드에는 선택 사항을 사용하지 않습니다. 또는 패키지 전용 클래스의 메서드를 호출하는 메서드의 경우),하지만 애플리케이션에서 서로 다른 '관심'(또는 레이어) 의 얇은 경계존재하는 코드 (데이터 저장소를 쿼리하는 데 사용하는 인터페이스 / 클래스의 서명, 예를 들어, 또는 null 속성을 가질 수있는 데이터를 '전송'하는 데 사용되는 pojos (DTO 또는보다 일반적인 설명, 다른 모듈의 게시 된 API)는 다른 우려가있는 다른 영역으로 null이 '누출'되는 것을 방지해야합니다.


Guava와 비교할 때 한 가지 성가신 문제 java.util.Optional는 다음과 같은 방법을 제공하지 않는다는 것입니다.

orElse(Optional<T>): Optional<T>

반면에 다음과 com.google.common.base.Optional같이 정의 됩니다.

or(Optional<T>): Optional<T>

이 특정 기능이 없기 때문에 Java 8 옵션의 모나 딕 응용 프로그램이 제한됩니다.

최신 정보:

Guava or(Optional<T>)는 Java 8 옵션과 같이 복제 할 수 있습니다.

optionalA.map(Optional::of).orElse(optionalB)

또는

optionalA.map(Optional::of).orElseGet(() -> computeOptionalB)

최신 정보:

에서 자바 9 (! 마지막으로) 당신은 사용할 수 있습니다 Optional.or(Supplier<Optional<T>>):

optionalA.or(() -> computeOptionalB)

그거 멋지다!

참고 URL : https://stackoverflow.com/questions/18681243/should-i-use-java8-guava-optional-for-every-method-that-may-return-null

반응형