[java] Guava의 선택적 수업의 요점은 무엇입니까

나는 최근에 이것에 대해 읽고이 클래스를 사용하는 사람들을 보았지만 거의 모든 경우에 사용 null하는 것도 효과적이었을 것입니다. 누군가 Optionalnull할 수 없거나 훨씬 더 깔끔한 방법으로 달성 할 수있는 구체적인 예를 제공 할 수 있습니까 ? 내가 생각할 수있는 유일한 것은 키를 Maps받아들이지 않는 것과 함께 사용하는 것입니다 null. 그러나 그것은 null 값의 사이드 “매핑”으로 수행 될 수 있습니다. 누구든지 더 설득력있는 주장을 할 수 있습니까? 감사합니다.



답변

구아바 팀원이 여기 있습니다.

아마도 가장 큰 단점은 null주어진 문맥에서 그것이 무엇을 의미해야하는지 명확하지 않다는 것입니다 : 설명적인 이름이 없습니다. null“이 매개 변수에 대한 값이 없음” 을 의미하는 것이 항상 분명한 것은 아닙니다 . 반환 값으로서 때로는 “오류”또는 “성공”(!!)을 의미하거나 단순히 “정답은 아무것도 아닙니다”를 의미합니다. Optional변수를 nullable로 만들 때 실제로 의미하는 개념이지만 항상 그런 것은 아닙니다. 그렇지 않은 경우 Optional실제로 의미하는 바를 명확히하기 위해 유사 하지만 다른 이름 지정 체계를 사용 하여 고유 한 클래스를 작성하는 것이 좋습니다 .

하지만 가장 큰 장점은 Optional가독성이 아니라 멍청한 증거라는 것입니다. 프로그램이 컴파일되기를 원한다면 결석 사건에 대해 적극적으로 생각해야합니다 Optional. 그 사건 을 적극적으로 풀고 해결해야하기 때문입니다. Null은 단순히 일을 잊는 것을 방해 할 정도로 쉽게 만들고 FindBugs가 도움이되지만 문제를 거의 해결하지 못한다고 생각합니다. 이는 “존재”할 수도 있고 없을 수도있는 값을 반환 할 때 특히 관련이 있습니다. 당신 (및 다른 사람들)은 구현할 때 잊을 수있는 것보다 값을 other.method(a, b)반환 할 수있는 것을 잊을 가능성이 훨씬 더 높습니다 . 복귀nullanullother.methodOptional 호출자가 개체를 직접 풀어야하므로 해당 사례를 잊을 수 없습니다.

이러한 이유로 Optional메서드에 대한 반환 유형으로 사용하는 것이 좋지만 메서드 인수에서 반드시 사용할 필요는 없습니다.

(이것은 여기 에서 논의한 내용 입니다.)


답변

MaybeHaskell 의 Monad 패턴 처럼 보입니다 .

다음을 읽어야합니다. Wikipedia Monad (기능적 프로그래밍) :

그리고 Monad로 사용되는 Guava의 선택 사항에 대해 논의하는 Kerflyn의 블로그 에서 From Optional to Monad with Guava읽으십시오 .


편집 :
Java8에는 .NET과 같은 모나 딕 연산자가있는 기본 제공 옵션이 있습니다 flatMap. 이것은 논란의 여지가있는 주제 였지만 마침내 구현되었습니다.

참조 http://www.nurkiewicz.com/2013/08/optional-in-java-8-cheat-sheet.html를

public Optional<String> tryFindSimilar(String s)  //...

Optional<Optional<String>> bad = opt.map(this::tryFindSimilar);
Optional<String> similar =       opt.flatMap(this::tryFindSimilar);

flatMap운영자는 쉽게 체인 호출 모든 반환 옵션 결과 모나드 운영 및 허가를 허용하는 것이 필수적입니다.

생각해보세요. map연산자를 5 번 사용하면으로 끝나고 Optional<Optional<Optional<Optional<Optional<String>>>>>를 사용 flatMap하면Optional<String>

Java8 이후로 덜 강력한 Guava의 Optional을 사용하지 않을 것입니다.


답변

그것을 사용하는 한 가지 좋은 이유는 null을 매우 의미있게 만드는 것입니다. 많은 것을 의미 할 수있는 null을 반환하는 대신 (예 : 오류, 실패 또는 비어 있음) null에 ‘이름’을 넣을 수 있습니다. 이 예를보십시오 :

기본 POJO를 정의 할 수 있습니다.

class PersonDetails {

String person;
String comments;

public PersonDetails(String person, String comments) {
    this.person = person;
    this.comments = comments;
}

public String getPerson() {
    return person;
}


public String getComments() {
    return comments;
}

}

이제이 간단한 POJO를 사용해 보겠습니다.

public Optional<PersonDetails> getPersonDetailstWithOptional () {

  PersonDetails details = null; /*details of the person are empty but to the caller this is meaningless,
  lets make the return value more meaningful*/


    if (details == null) {
      //return an absent here, caller can check for absent to signify details are not present
        return Optional.absent();
    } else {
      //else return the details wrapped in a guava 'optional'
        return Optional.of(details);
    }
}

이제 null 사용을 피하고 Optional로 확인하여 의미있는

public void checkUsingOptional () {

    Optional<PersonDetails> details = getPersonDetailstWithOptional();

    /*below condition checks if persons details are present (notice we dont check if person details are null,
    we use something more meaningful. Guava optional forces this with the implementation)*/
    if (details.isPresent()) {

      PersonDetails details = details.get();

        // proceed with further processing
        logger.info(details);

    } else {
        // do nothing
        logger.info("object was null");
    }

    assertFalse(details.isPresent());
}

따라서 결국 null을 의미 있고 모호하지 않게 만드는 방법입니다.


답변

Optional의 가장 중요한 장점은 함수 구현 자와 호출자 간의 계약에 더 많은 세부 정보를 추가한다는 것입니다. 이러한 이유로 매개 변수와 반환 유형 모두에 유용합니다.

Optional가능한 null 개체에 대해 항상 사용하도록 규칙을 만들면 다음 과 같은 경우에 더 많은 설명을 추가합니다.

  1. Optional<Integer> maxPrime(Optional<Integer> from, Optional<Integer> to)

    여기의 계약은 결과가 반환되지 않을 가능성이 있음을 명확하게 명시하지만, 결과가 함께 작동 from하고 to부재 함을 보여줍니다 .

  2. Optional<Integer> maxPrime(Optional<Integer> from, Integer to)

    계약은 from이 선택 사항이므로 없는 값이 start from 2와 같은 특별한 의미를 가질 수 있음을 지정합니다. to매개 변수 의 null 값 이 예외를 throw 할 것으로 예상 할 수 있습니다 .

옵션을 사용하는 좋은 부분 그래서 계약 (유사한 모두 설명 된 것입니다 @NotNull당신이 코드를 작성해야하기 때문에 주석)뿐만 아니라 형식적인 .get()대처를 Optional.


답변