programing

Java 8 getter는 옵션타입을 반환해야 합니까?

prostudy 2022. 8. 2. 22:20
반응형

Java 8 getter는 옵션타입을 반환해야 합니까?

Optional자바8에서 도입된 타입은 많은 개발자들에게 새로운 것입니다.

getter 메서드가 반환되는가?Optional<Foo>고전을 대신해서 타이핑하다Foo좋은 방법?값이 다음과 같을 수 있다고 가정합니다.null.

물론 사람들은 그들이 원하는 것을 할 것이다.다만, 이 기능을 추가할 때는 명확한 의도가 있었습니다.일반적인 용도는 아닙니다.아마도 많은 분들이 원하셨을 겁니다.우리의 의도는 "결과 없음"을 나타내는 명확한 방법이 필요한 라이브러리 메서드 반환 유형을 위한 제한적인 메커니즘을 제공하고null이는 오류를 일으킬 가능성이 압도적으로 높기 때문이다.

예를 들어 결과 배열 또는 결과 목록을 반환하는 항목에 이 명령을 사용하면 안 됩니다. 대신 빈 배열 또는 목록을 반환해야 합니다.이 필드를 어떤 필드나 메서드 매개 변수로 사용하면 안 됩니다.

저는 그것을 일상적으로 getters의 리턴밸류로서 사용하는 것은 분명히 과잉사용이라고 생각합니다.

Optional은 피해야 하는 것은 문제될 것이 없습니다.많은 사람들이 바라는 것과 다를 뿐이기 때문에 과도한 사용의 위험이 상당히 우려되고 있습니다.

(공공서비스 공지: NEVER callOptional.get그것이 결코 무효가 되지 않는다는 것을 증명할 수 없는 한, 대신 다음과 같은 안전한 방법 중 하나를 사용합니다.orElse또는ifPresent돌이켜보면 전화했어야 했는데get비슷한 것getOrElseThrowNoSuchElementException아니면 이것이 매우 위험한 방법이라는 것을 훨씬 더 명확히 하는 어떤 것이든 간에Optional애초에.교훈을 얻었습니다. (업데이트: Java 10은Optional.orElseThrow()(의미적으로는 와 동등)get()(단, 그 이름이 더 적절합니다.

저만의 연구를 조금 한 후, 이것이 적절한 시기에 제안될 수 있는 많은 것들을 발견했습니다.Oracle 기사에서 가장 신뢰할 수 있는 인용문은 다음과 같습니다.

「옵션 클래스의 의도는, 모든 늘 참조를 치환하는 것은 아닙니다. 대신에, 그 목적은 보다 이해하기 쉬운 API를 설계하는 것입니다.그러면 메서드의 시그니처를 읽는 것만으로 옵션 값을 기대할 수 있는지 여부를 알 수 있습니다. 그러면 값의 부재를 처리하기 위해 Optional을 적극적으로 풀어야 합니다." - Null Pointer Exceptions에 지쳤습니까? Java SE 8의 옵션 사용을 검토하십시오!

Java 8 Optional에서 발췌한 내용도 있습니다. 사용방법

"옵션으로는 아무것도 얻을 수 없기 때문에 이러한 컨텍스트에서 사용할 수 없습니다.

  • 도메인 모델레이어(시리얼화 불가)
  • DTO(동일한 이유)
  • 메서드의 입력 매개 변수에서
  • 생성자 매개 변수에서"

그리고 몇 가지 타당한 점들이 제기되는 것 같습니다.

부정적인 의미나 위험 신호를 찾을 수 없었습니다Optional피해야 합니다.API의 유용성이나 사용 편의성이 향상되면 사용한다는 것이 일반적인 생각입니다.

일반적으로 생략 가능한 반환값에는 옵션 유형을 사용하는 것이 좋습니다.그러나 프레임워크에 대해서는 기존 getter를 옵션 타입으로 대체하면 getter와 setter의 코딩 규칙에 의존하는 프레임워크(예를 들어 hibernate)를 사용할 때 큰 문제가 발생할 것으로 생각합니다.

이유OptionalJava에 추가된 이유는 다음과 같습니다.

return Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
    .stream()
    .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
    .filter(m ->  Arrays.equals(m.getParameterTypes(), parameterClasses))
    .filter(m -> Objects.equals(m.getReturnType(), returnType))
    .findFirst()
    .getOrThrow(() -> new InternalError(...));

보다 깨끗합니다.

Method matching =
    Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
    .stream()
    .filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
    .filter(m ->  Arrays.equals(m.getParameterTypes(), parameterClasses))
    .filter(m -> Objects.equals(m.getReturnType(), returnType))
    .getFirst();
if (matching == null)
  throw new InternalError("Enclosing method not found");
return matching;

요점은 Optional은 기능 프로그래밍을 지원하기 위해 작성되었으며 동시에 Java에 추가되었다는 입니다.(이 예시는 Brian Goetz의 블로그를 인용한 것입니다.더 좋은 예로는orElse()method, 이 코드에서는 예외는 발생하지만 상황은 알 수 있습니다.)

하지만 지금 사람들은 Optional을 매우 다른 이유로 사용하고 있습니다.언어 디자인의 결함을 해결하기 위해 사용하는 거야결점은 다음과 같습니다.API의 파라미터와 반환값 중 어느 것이 null로 허용되는지 지정할 수 없습니다.javadocs에서 언급될 수 있지만, 대부분의 개발자는 코드를 위해 javadocs를 작성하지도 않으며, 작성 시 javadocs를 확인하는 사람도 많지 않습니다.따라서 콜 스택에서 이미9~10회 반복 검증되었기 때문에 null일 수 없는 경우가 많지만, 이 값을 사용하기 전에 반드시 null 값을 체크하는 많은 코드가 발생합니다.

새로운 Optional 클래스를 본 많은 사람들이 API에 명확성을 추가하는 것이 목적이라고 생각했기 때문에 이 결함을 해결하고 싶은 욕구가 있었던 것 같습니다.그렇기 때문에 "옵션을 반환해야 합니까?"와 같은 질문을 하는 것입니다.아니요, getter가 함수형 프로그래밍에 사용될 것으로 예상하지 않는 한, 아마 사용하지 않는 것이 좋습니다.실제로 Java API에서 Optional이 사용되는 위치를 살펴보면 기능 프로그래밍의 핵심인 Stream 클래스가 주를 이루고 있습니다.(정확히 확인하지는 않았지만 Stream 클래스만 사용할 수 있습니다.)

기능 코드에서 getter를 사용할 계획이라면 표준 getter와 Optional을 반환하는 두 번째 getter를 사용하는 것이 좋습니다.

아, 그리고 만약 당신이 당신의 수업을 직렬화 할 수 있어야 한다면, 당신은 절대 Optional을 사용하지 말아야 합니다.

옵션은 API의 결함에 대한 매우 나쁜 해결책입니다.a) 매우 상세하고 b) 처음부터 이 문제를 해결하기 위한 것이 아니기 때문입니다.

API 결함에 대한 훨씬 더 나은 솔루션은 Nullness Checker입니다.이것은 @Nullable로 주석을 달아 null이 허용되는 파라미터 및 반환값을 지정할 수 있는 주석 프로세서입니다.이렇게 하면 컴파일러는 코드를 스캔하여 실제로 null일 수 있는 값이 null이 허용되지 않는 값으로 전달되는지 여부를 확인할 수 있습니다.기본적으로는 주석이 없는 한 어떤 것도 null이 될 수 없다고 가정합니다.이렇게 하면 null 값에 대해 걱정할 필요가 없습니다.매개 변수에 null 값을 전달하면 컴파일러 오류가 발생합니다.개체를 테스트하여 null일 수 없는 null을 사용하면 컴파일러 경고가 발생합니다.이로 인해 Null Pointer가 변경됩니다.런타임 오류에서 컴파일 시간 오류까지의 예외입니다.

이것으로 모든 것이 바뀝니다.

getter에 대해서는, Optional을 사용하지 말아 주세요.그리고 어떤 멤버도 null이 될 수 없도록 당신의 클래스를 설계해 보세요.또한 프로젝트에 Nullness Checker를 추가하여 필요에 따라 getters 및 setter parameter @Nullable을 선언해 보십시오.새로운 프로젝트만 해봤어요.불필요한 null 테스트로 작성된 기존 프로젝트에서 경고가 많이 발생하므로 개조가 어려울 수 있습니다.하지만 그것은 또한 많은 벌레들을 잡을 것이다.난 그것을 좋아해.덕분에 내 코드가 훨씬 더 깨끗하고 신뢰할 수 있게 되었다.

(이 문제를 해결하는 새로운 언어도 있습니다.Kotlin은 Java 바이트 코드로 컴파일되며 선언할 때 개체가 null일 수 있는지 여부를 지정할 수 있습니다.보다 깔끔한 어프로치입니다).

원본 투고 부록 (버전 2)

심사숙고 끝에 저는 마지못해 한 가지 조건으로 Optional을 반품할 수 있다는 결론에 도달했습니다.취득한 값이 실제로는 null일 수 있습니다.나는 사람들이 게터로부터 Optional을 정기적으로 반환하는 많은 코드를 봐왔다.코드만 복잡해져 버그가 발생할 가능성이 높아지는 매우 나쁜 코딩 관행이라고 생각합니다.그러나 반환된 값이 실제로 null일 수 있는 경우에는 Optional(선택사항)으로 래핑합니다.

기능 프로그래밍용으로 설계된 메서드와 함수 참조가 필요한 메서드는 두 가지 형식으로 작성됩니다(및 그 중 하나는 Optional(옵션)을 사용합니다).예를들면,Optional.map()그리고.Optional.flatMap()둘 다 함수 참조를 사용합니다.첫 번째는 일반 getter를 참조하고 두 번째는 Optional을 반환하는 getter를 참조합니다.따라서 값이 null일 수 없는 Optional을 반환하는 것은 다른 사람에게 도움이 되지 않습니다.

하지만 Nullness Checker가 Null Pointer를 전환하기 때문에 Nullness Checker가 사용하는 접근법이 Null을 처리하는 가장 좋은 방법이라고 생각합니다.런타임 버그에서 컴파일 시간 오류에 대한 예외입니다.

최신 시리얼라이저 및 기타 프레임워크를 사용하는 경우Optional그리고 는 이 지침들이 글을 쓸 때 잘 작동한다는 것을 알았다.Entity콩 및 도메인 계층:

  1. 시리얼라이제이션레이어(통상은 DB)에 의해서, 다음의 설정이 허가되는 경우.null열의 셀 값BAR식탁에 올라서FOO, 그 후 getterFoo.getBar()돌아올 수 있다Optional개발자에게 이 값이 null이 될 것으로 예상될 수 있으며 이 값은 개발자가 처리해야 함을 나타냅니다.DB가 값이 null이 아님을 보증하는 경우 getter는 이 값을 null로 감싸지 않아야 합니다.Optional.
  2. Foo.bar그래야 한다private 아니다Optional정말 그럴 이유가 없어요Optional그렇다면private.
  3. 세터Foo.setBar(String bar)타입을 취할 필요가 있다bar 아니라 Optional를 사용해도 괜찮다면null인수에서 이를 JavaDoc 코멘트에 기술합니다.사용해도 괜찮다면null한 사람IllegalArgumentException또는 IMHO가 더 적절하다는 비즈니스 로직도 있습니다.
  4. 컨스트럭터에는 필요 없음Optional(포인트 3과 유사한 이유로) 인수.일반적으로 시리얼화 데이터베이스에 null이 아닌 인수만 생성자에 포함합니다.

위의 내용을 보다 효율적으로 하기 위해 IDE 템플릿을 편집하여 getter 및 대응하는 템플릿을 생성할 수 있습니다.toString(),equals(Obj o)또는 필드를 직접 사용합니다(대부분의 IDE 생성기는 이미 늘을 처리합니다).

자주 인용되는 조언은 Java 이외의 경험이나 옵션 유형, 기능 프로그래밍 경험이 적은 사람들에게서 나온 것임을 명심해야 합니다.

그러니 조금의 의심도 없이 받아들이세요.그 대신에, 「우량한 프랙티스」의 관점에서 생각해 봅시다.

모범 사례란 "새로운 코드를 어떻게 작성합니까?"를 묻는 것뿐만 아니라 "기존 코드는 어떻게 됩니까?"를 묻는 것입니다.

의 경우Optional, 환경에 따라서는, 다음과 같은 알기 쉽고 좋은 답을 찾을 수 있었습니다.

Optional에서의 옵션값 지정은 필수입니다.records:

record Pet(String name, Optional<Breed> breed,
Optional<ZonedDateTime> dateOfBirth)

즉, 기존 코드는 현재 상태로는 양호하지만 다음 코드를 사용하는 경우record(즉, 「새로운 코드」)는, 광범위한 채용을 일으킵니다.Optional그 주위에.

그 결과는 가독성과 신뢰성 면에서 완전한 성공을 거두었다.그만 쓰세요null.

언급URL : https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type

반응형

'programing' 카테고리의 다른 글

vue-cli 프로젝트에서 공용 폴더 변경  (0) 2022.08.02
2방향 바인딩 Nuxt.js  (0) 2022.08.02
Vue.js 동적 컴포넌트 및 목록  (0) 2022.08.02
C의 MIN과 MAX  (0) 2022.08.02
Vuejs Axios 데이터가 표시되지 않음  (0) 2022.08.02