나는 최근에 이것에 대해 읽고이 클래스를 사용하는 사람들을 보았지만 거의 모든 경우에 사용 null
하는 것도 효과적이었을 것입니다. 누군가 Optional
가 null
할 수 없거나 훨씬 더 깔끔한 방법으로 달성 할 수있는 구체적인 예를 제공 할 수 있습니까 ? 내가 생각할 수있는 유일한 것은 키를 Maps
받아들이지 않는 것과 함께 사용하는 것입니다 null
. 그러나 그것은 null 값의 사이드 “매핑”으로 수행 될 수 있습니다. 누구든지 더 설득력있는 주장을 할 수 있습니까? 감사합니다.
답변
구아바 팀원이 여기 있습니다.
아마도 가장 큰 단점은 null
주어진 문맥에서 그것이 무엇을 의미해야하는지 명확하지 않다는 것입니다 : 설명적인 이름이 없습니다. null
“이 매개 변수에 대한 값이 없음” 을 의미하는 것이 항상 분명한 것은 아닙니다 . 반환 값으로서 때로는 “오류”또는 “성공”(!!)을 의미하거나 단순히 “정답은 아무것도 아닙니다”를 의미합니다. Optional
변수를 nullable로 만들 때 실제로 의미하는 개념이지만 항상 그런 것은 아닙니다. 그렇지 않은 경우 Optional
실제로 의미하는 바를 명확히하기 위해 유사 하지만 다른 이름 지정 체계를 사용 하여 고유 한 클래스를 작성하는 것이 좋습니다 .
하지만 가장 큰 장점은 Optional
가독성이 아니라 멍청한 증거라는 것입니다. 프로그램이 컴파일되기를 원한다면 결석 사건에 대해 적극적으로 생각해야합니다 Optional
. 그 사건 을 적극적으로 풀고 해결해야하기 때문입니다. Null은 단순히 일을 잊는 것을 방해 할 정도로 쉽게 만들고 FindBugs가 도움이되지만 문제를 거의 해결하지 못한다고 생각합니다. 이는 “존재”할 수도 있고 없을 수도있는 값을 반환 할 때 특히 관련이 있습니다. 당신 (및 다른 사람들)은 구현할 때 잊을 수있는 것보다 값을 other.method(a, b)
반환 할 수있는 것을 잊을 가능성이 훨씬 더 높습니다 . 복귀null
a
null
other.method
Optional
호출자가 개체를 직접 풀어야하므로 해당 사례를 잊을 수 없습니다.
이러한 이유로 Optional
메서드에 대한 반환 유형으로 사용하는 것이 좋지만 메서드 인수에서 반드시 사용할 필요는 없습니다.
답변
Maybe
Haskell 의 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 개체에 대해 항상 사용하도록 규칙을 만들면 다음 과 같은 경우에 더 많은 설명을 추가합니다.
-
Optional<Integer> maxPrime(Optional<Integer> from, Optional<Integer> to)
여기의 계약은 결과가 반환되지 않을 가능성이 있음을 명확하게 명시하지만, 결과가 함께 작동
from
하고to
부재 함을 보여줍니다 . -
Optional<Integer> maxPrime(Optional<Integer> from, Integer to)
계약은 from이 선택 사항이므로 없는 값이 start from 2와 같은 특별한 의미를 가질 수 있음을 지정합니다.
to
매개 변수 의 null 값 이 예외를 throw 할 것으로 예상 할 수 있습니다 .
옵션을 사용하는 좋은 부분 그래서 계약 (유사한 모두 설명 된 것입니다 @NotNull
당신이 코드를 작성해야하기 때문에 주석)뿐만 아니라 형식적인 .get()
대처를 Optional
.