<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Java 8 `Optional`:完整參考 > 原文: [https://howtodoinjava.com/java8/java-8-Optional-complete-reference/](https://howtodoinjava.com/java8/java-8-Optional-complete-reference/) 我們所有人都必須在我們的應用程序中遇到`NullPointerException`。 當您嘗試利用尚未初始化的對象引用,使用`null`初始化或根本不指向任何實例的對象引用時,會發生此異常。***`NULL`僅表示“不存在值”***。 羅馬人很可能只是一個人,沒有遇到這個空缺的問題,而是從 I,II,III 開始計數(不為零)。 也許,他們無法模擬市場上蘋果的缺乏。:-) “我稱之為我十億美元的錯誤。” – [**C. A. R. Hoare Hoare**](https://en.wikipedia.org/wiki/C._A._R._Hoare "C._A._R._Hoare"),他發明了空引用 在本文中,我將針對該特定用例(即[`Optional`](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html "Optional"))討論 [**java 8 特性之一**](//howtodoinjava.com/category/java8/ "java 8")。 為了清楚和區分多個概念,本文分為多個部分。 ```java Discussion Points 1) What is the Type of Null? 2) What is wrong with just returning null? 3) How Java 8 Optional provide the solution? a) Creating Optional objects b) Do something if a value is present c) Default/Absent values and actions d) Rejecting certain values Using the filter method 4) What is inside Optional make it work? 5) What is Optional trying to solve? 6) What is Optional not trying to solve? 7) How should Optional be used? 8) Conclusion ``` ## 1)什么是空值? 在 Java 中,我們使用引用類型來訪問對象,而當我們沒有特定的對象作為引用點時,則將此類引用設置為`null`表示沒有值。是吧? `null`的使用是如此普遍,以至于我們很少對此多加思考。 例如,對象的字段成員會自動初始化為`null`,而程序員通常會在沒有初始值的引用類型時將引用類型初始化為`null`,并且通常在每次我們不知道或不知道的時候都使用`null`沒有參考價值。 僅供參考,在 Java 中`null`實際上是一種類型,是一種特殊的類型。 它沒有名稱,因此我們不能聲明其類型的變量或將任何變量強制轉換為它。 實際上,只有一個可以與之關聯的值(即字面值為`null`)。 請記住,與 Java 中的任何其他類型不同,可以將空引用安全地分配給任何其他引用類型,而不會出現任何錯誤(見 [**JLS 3.10.7**](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.7 "jls 3.10.7") 和 [**4.1**](https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.1 "jls 4.1"))。 ## 2)僅返回`null`有什么問題? 通常,API 設計人員將描述性的 Java 文檔放入 API 中,并在其中提到 API 可以返回空值,在這種情況下,返回值可以是`null`。 現在,問題在于 API 的調用者可能由于任何原因而錯過了讀取 Javadoc 的操作,并且**忘記了處理空值**的情況。 肯定的將來這將是一個錯誤。 并且相信我,這經常發生,并且是空指針異常的主要原因之一,盡管不是唯一的原因。 因此,在這里上一課,當您第一次使用它時,請務必(至少)閱讀它的 Javadocs。 > 現在我們知道在大多數情況下`null`是一個問題,什么是最好的處理方式? 一個好的解決方案是始終**始終使用某個值**初始化您的對象引用,而永遠不要使用`null`進行初始化。 這樣,您將永遠不會遇到`NullPointerException`。 很公平。 但實際上,我們始終沒有默認值作為參考。 那么,這些案件應該如何處理? 上述問題在許多方面都是正確的。 好吧, **java 8 `Optional`** 是這里的答案。 ## 3)Java 8 `Optional`如何提供解決方案? 可選的是用非空值替換可空`T`引用的方法。 `Optional`可以包含非空`T`引用(在這種情況下,我們稱該引用為“存在”),也可以不包含任何內容(在這種情況下,我們稱該引用為“不存在”)。 > 請記住,**從未說過`Optional`“包含`null`”**。 ```java Optional<Integer> canBeEmpty1 = Optional.of(5); canBeEmpty1.isPresent(); // returns true canBeEmpty1.get(); // returns 5 Optional<Integer> canBeEmpty2 = Optional.empty(); canBeEmpty2.isPresent(); // returns false ``` 您也可以**將`Optional`看做為包含或不包含值**的單值容器。 重要的是要注意,`Optional`類的目的不是替換每個單個空引用。 相反,它的目的是**幫助設計更易于理解的 API** ,以便僅通過讀取方法的簽名即可知道是否可以期望一個可選值。 這迫使您從`Optional`中獲取值并對其進行處理,同時處理`Optional`為空的情況。 好吧,這正是空引用/返回值的解決方案,最終導致`NullPointerException`。 以下是一些示例,以了解有關應如何在應用程序代碼中創建和使用`Optional`的更多信息。 ## a)創建`Optional`對象 創建`Optional`的主要方法有 3 種。 i)使用`Optional.empty()`創建空的`Optional`。 ```java Optional<Integer> possible = Optional.empty(); ``` ii)使用`Optional.of()`創建具有默認非空值的`Optional`。 如果在`of()`中傳遞`null`,則立即引發`NullPointerException`。 ```java Optional<Integer> possible = Optional.of(5); ``` iii)使用`Optional.ofNullable()`創建一個可能包含空值的`Optional`對象。 如果參數為`null`,則生成的`Optional`對象將為空(請記住,該值不存在;請勿將其讀取為`null`)。 ```java Optional<Integer> possible = Optional.ofNullable(null); //or Optional<Integer> possible = Optional.ofNullable(5); ``` ## b)如果存在`Optional`值,則執行某些操作 第一步是獲取`Optional`對象。 現在,在檢查其內部是否包含任何值之后,再使用它。 ```java Optional<Integer> possible = Optional.of(5); possible.ifPresent(System.out::println); ``` 您也可以將以下代碼覆蓋為上面的代碼。 但是,不建議您使用`Optional`,因為與嵌套的空檢查相比,它沒有太大的改進。 它們看起來確實完全相似。 ```java if(possible.isPresent()){ System.out.println(possible.get()); } ``` 如果`Optional`對象為空,則不會打印任何內容。 ## c)默認/不存在的值和動作 如果確定操作結果為空,則編程中的典型模式是返回默認值。 通常,您可以使用三元運算符。 但是使用`Optional`,您可以編寫如下代碼: ```java //Assume this value has returned from a method Optional<Company> companyOptional = Optional.empty(); //Now check optional; if value is present then return it, //else create a new Company object and retur it Company company = companyOptional.orElse(new Company()); //OR you can throw an exception as well Company company = companyOptional.orElseThrow(IllegalStateException::new); ``` ## d)使用過濾方法拒絕某些值 通常,您需要在對象上調用方法并檢查某些屬性。 例如在下面的示例代碼中,檢查公司是否設有“財務”部門; 如果有,請打印出來。 ```java Optional<Company> companyOptional = Optional.empty(); companyOptional.filter(department -> "Finance".equals(department.getName()) .ifPresent(() -> System.out.println("Finance is present")); ``` [**過濾方法**](//howtodoinjava.com/java8/java-8-tutorial-streams-by-examples/ "java 8 streams")以[**謂詞**](//howtodoinjava.com/2014/04/04/how-to-use-predicate-in-java-8/ "predicate")為參數。 如果`Optional`對象中存在一個值,并且該值與謂詞匹配,則過濾方法將返回該值;否則,該方法將返回該值。 否則,它返回一個空的`Optional`對象。 如果在[`Stream`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html "Stream")接口中使用了過濾方法,則可能已經看到了類似的模式。 很好,這段代碼看起來更接近問題語句,并且沒有妨礙我們進行冗長的`null`檢查! 哇!! 從編寫痛苦的嵌套`null`檢查到編寫可編寫,可讀且可更好地免受`null`指針異常保護的聲明性代碼,我們已經走了很長一段路。 ## 4)`Optional`內部有什么使它起作用? 如果打開`Optional.java`的源代碼,則會發現`Optional`持有的值定義為: ```java /** * If non-null, the value; if null, indicates no value is present */ private final T value; ``` 并且,如果您定義一個空的`Optional`,則它聲明如下。 **靜態關鍵字可確保每個 VM** 通常僅存在一個空實例。 ```java /** * Common instance for {@code empty()}. */ private static final Optional<?> EMPTY = new Optional<>(); ``` 默認的**無參構造器定義為私有** ,因此您無法創建`Optional`的實例,但上述三種方法除外。 當您創建一個`Optional`時,最終會發生以下調用,并將傳遞的值分配給“`value`”屬性。 ```java this.value = Objects.requireNonNull(value); ``` 當您嘗試從`Optional`獲取值時,如果沒有拋出`NoSuchElementException`,則會獲取該值: ```java public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } ``` 同樣,在`Optional`類中定義的其他函數僅在“`value`”屬性附近起作用。 瀏覽`Optional.java`的[**源代碼**](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/Optional.java "Optional.java")以獲取更多信息。 ## 5)`Optional`試圖解決什么? `Optional`嘗試通過考慮到有時缺少返回值來增加構建更具表現力的 API 的可能性,從而減少 Java 系統中空指針異常的數量。 如果從一開始就存在`Optional`,那么今天大多數庫和應用程序可能會更好地處理缺少的返回值,從而減少了空指針異常的數量以及總體上的錯誤總數。 通過使用`Optional`,用戶不得不考慮特殊情況。 除了因提供空名而提高了可讀性之外,`Optional`的**最大優點是其防白癡**。 如果您要完全編譯程序,它會迫使您積極考慮不存在的情況,因為您必須主動展開`Optional`并解決該失敗情況。 ## 6)`Optional`不嘗試解決的問題是什么? `Optional`**并不是要避免所有類型的空指針**的機制。 例如方法和構造器的強制輸入參數仍然必須進行測試。 就像使用`null`時一樣,`Optional`不能幫助傳達缺失值的含義。 因此,該方法的調用者仍然必須檢查 API 的 javadoc,以了解缺少`Optional`的含義,以便對其進行正確處理。 請注意,`Optional`不能在以下情況下使用,因為它可能不會給我們帶來任何好處: * 在域模型層(不可序列化) * 在 DTO 中(不可序列化) * 在方法的輸入參數中 * 在構造器參數中 ## 7)應該如何使用`Optional`? **幾乎在所有時間**都應該使用`Optional`**作為可能不返回值的函數**的返回類型。 這是來自 OpenJDK 郵件列表的引言: > JSR-335 EG 相當強烈地認為`Optional`不應僅用于支持 option-return 慣例。 > > 有人建議甚至將其重命名為“`OptionalReturn`”。 從本質上講,這意味著`Optional`僅應在確實達到目的的情況下用作某些服務,存儲庫或工具方法的返回類型。 ## 8)總結 在本文中,我們了解了如何采用新的 **Java SE 8 `java.util.Optional`**。`Optional`的目的不是替換代碼庫中的每個單個`null`引用,而是幫助您設計更好的 API,其中,僅通過讀取方法的簽名,用戶就可以知道是否期待并妥善處理`Optional`值。 僅此特性就可以了。 在評論部分讓我知道您的想法。 **祝您學習愉快!**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看