比方說,你想要獲取函數返回的字符串,將其轉換爲大寫,然後將其打印出來。如果您有:
String someFunc() { ... }
你也許會這樣寫:
System.out.println(someFunc().toUpperCase());
當然,這將引發NullPointerException
如果someFunc
回報null
。相反,假設我們有這樣的:
Optional<String> someFunc() { ... }
然後
System.out.println(someFunc().toUpperCase());
將無法正常工作,因爲Optional
沒有一個toUpperCase
方法。在這一點上 - 希望 - 你會面臨Optional
,這應該讓你考慮Optional
是空的情況。這有助於避免NPE,但可能只是有點。
現在您可能會專注於如何從Optional
中獲取價值,並且您可能會忘記空的情況。嗯,有一個get
方法:
System.out.println(someFunc().get().toUpperCase());
這帶回了同樣的問題作爲NPE,除了例外是NoSuchElementException
代替。所以,如果你在Optional
上盲目地調用get
,它確實與在引用上調用方法而不檢查其是否爲空幾乎是相同的。
(出於這個原因,Brian Goetz認爲Optional.get
是用Java 8中最大的錯誤見他與安格蘭格JAX 2015 Fragen und Antworten zu Java 8接受採訪時約16分鐘。我不知道這是最大的,但它是一個錯誤。人們只是不要指望get
拋出異常。)
如果你勤於檢查空引用或空自選,然後
Optional<String> os = someFunc();
if (os.isPresent()) {
System.out.println(os.get().toUpperCase());
}
幾乎比老
更好
String s = someFunc();
if (s != null) {
System.out.println(s.toUpperCase());
}
的真正優勢的Optional
是,它是一個庫類,它具有處理以安全的方式空的情況下相當豐富的API。通常可以通過將方法調用鏈接到首先返回Optional
的方法來處理Optional
中可能包含的值。例如,以上如下,我們可以把樣品:
someFunc().map(String::toUpperCase)
.ifPresent(System.out::println);
的可能的複製[用於可選用途]的(http://stackoverflow.com/questions/23454952/uses-for-optional) –
可能的複製[可選與空。在Java 8中可選的目的是什麼?](http://stackoverflow.com/questions/28746482/optional-vs-null-what-is-the-purpose-of-optional-in-java-8) – Mritunjay
那麼,一方面,你可以在不存在的'Optional'上使用'x.toString()',但是你不能在'null'上使用它。還有一些像'x.equals(y)'。 – ajb