<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 `NullPointerException` - 如何在 Java 中有效處理空指針 > 原文: [https://howtodoinjava.com/java/exception-handling/how-to-effectively-handle-nullpointerexception-in-java/](https://howtodoinjava.com/java/exception-handling/how-to-effectively-handle-nullpointerexception-in-java/) [**Java `NullPointerException`**](https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html "NullPointerException")是非受檢的異常,并且擴展了`RuntimeException`。 `NullPointerException`不會強迫我們使用`catch`塊來處理它。 對于大多數 Java 開發人員社區而言,此異常非常像一場噩夢。 當我們最不期望它們時,它們通常會彈出。 在尋找解決此類問題的原因和最佳方法時,我也花費了大量寶貴的時間。 我將在這里編寫一些[最佳實踐](https://howtodoinjava.com/java-best-practices/ "best practices guides"),這些最佳實踐遵循了行業慣例,一些專家講座以及我自己的經驗。 ```java Table of Contents 1\. Why NullPointerException occur in the code 2\. Common places where NullPointerException usually occur 3\. Best ways to avoid NullPointerException 4\. Available NullPointerException safe operations 5\. What if you must allow NullPointerException in some places ``` ## 1\. 為什么在代碼中出現`NullPointerException` `NullPointerException`是代碼中您嘗試訪問/修改尚未初始化的對象的情況。 從本質上講,這意味著*對象引用變量未指向*任何位置,并且未引用任何內容或引用了`null`。 一個拋出空指針異常的示例 Java 程序。 ```java package com.howtodoinjava.demo.npe; public class SampleNPE { public static void main(String[] args) { String s = null; System.out.println( s.toString() ); // 's' is un-initialized and is null } } ``` ## 2\. Java `NullPointerException`通常發生的常見位置 好吧,由于各種原因,`NullPointerException`可能會出現在代碼中的任何位置,但我根據自己的經驗準備了最常用的地點清單。 1. 在未初始化的對象上調用方法 2. 方法中傳遞的參數為`null` 3. 在`null`的對象上調用`toString()`方法 4. 在不檢查`null`相等性的情況下比較`if`塊中的對象屬性 5. 對于像 Spring 這樣的依賴注入的框架來說,配置不正確 6. 在`null`的對象上使用`synchronized` 7. 鏈接語句,即單個語句中的多個方法調用 這不是詳盡的清單。 還有其他幾個地方和原因。 如果您還可以回憶起其他任何內容,請發表評論。 它也會幫助其他人(初學者)。 ## 3\. 避免 Java `NullPointerException`的最佳方法 #### 3.1 三元運算符 如果[運算符](https://en.wikipedia.org/wiki/%3F:#Java "ternary operator")不為`null`,則結果為左側的值,否則求值右側。 它具有如下語法: ```java boolean expression ? value1 : value2; ``` 如果`expression`計算為`true`,則整個表達式將返回`value1`,否則返回`value2`。 它更像`if-else`構造,但是更有效和更具表現力。 為了防止`NullPointerException`(NPE),請像下面的代碼一樣使用此運算符: ```java String str = (param == null) ? "NA" : param; ``` #### 3.2 使用 Apache Commons `StringUtils`進行字符串操作 [Apache Commons lang](https://commons.apache.org/proper/commons-lang/ "common lang") 是幾個工具類的集合,用于各種操作之王。 其中之一是[`StringUtils.java`](https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html "StringUtils java doc")。 使用`StringUtils.isNotEmpty()`驗證作為參數傳遞的字符串是否為空或空字符串。 如果不為`null`或為空; 然后進一步使用它。 其他類似方法是`StringUtils.IsEmpty()`和 `StringUtils.equals()`。他們在自己的 javadocs 中聲稱,如果`StringUtils.isNotBlank()`拋出 NPE,則 API 中存在錯誤。 ```java if (StringUtils.isNotEmpty(obj.getvalue())){ String s = obj.getvalue(); .... } ``` #### 3.3 盡早檢查方法參數是否為空 您應該始終將輸入驗證置于方法的開頭,以使其余代碼不必處理輸入錯誤的可能性。 因此,如果有人傳遞空值,那么事情將在棧的早期破裂,而不是在更難以識別根本問題的更深的位置破裂。 *在大多??數情況下,針對快速失敗行為的選擇是一個不錯的選擇。* #### 3.4 考慮原始類型而不是對象 當對象引用指向無內容時,將發生空問題。 因此,盡可能多地使用原始類型始終是安全的,因為它們不會受到空引用的影響。 所有原始類型都必須附加一些默認值,因此請當心。 #### 3.5 仔細考慮鏈接方法調用 雖然鏈式語句很容易在代碼中查看,但它們不是 NPE 友好的。 一條分散在多行中的語句將為您提供棧跟蹤中第一行的行號,無論它出現在何處。 ```java ref.method1().method2().method3().methods4(); ``` 這些鏈接的語句將僅打印“`NullPointerException`在行號`xyz`中發生”。確實很難調試此類代碼。 避免這樣的調用。 #### 3.6 使用`String.valueOf()`而不是`toString()` 如果您必須打印任何對象的字符串表示形式,請不要使用`object.toString()`。 這是 NPE 的非常軟的目標。 而是使用`String.valueOf(object)`。 即使`object`在第二種方法中為`null`,它也不會給出異常,并且將輸出“`null`”到輸出流。 #### 3.7 避免從方法中返回`null` 避免 NPE 的一個很棒的技巧是返回空字符串或空集合,而不是返回`null`。 在您的應用程序中一致地執行此操作。 您會注意到,如果這樣做,則不需要進行大量的空檢查。 例如: ```java List<string> data = null; @SuppressWarnings("unchecked") public List getDataDemo() { if(data == null) return Collections.EMPTY_LIST; //Returns unmodifiable list return data; } ``` 使用上述方法的用戶即使錯過了空檢查,也不會看到難看的 NPE。 #### 3.8 不鼓勵傳遞空參數 我已經看到一些方法聲明,其中方法需要兩個或多個參數。 如果參數之一作為`null`傳遞,則方法以某種不同的方式起作用。 避免這種情況。 相反,您應該定義兩種方法; 一個帶有單個參數,第二個帶有兩個參數。 強制傳遞參數。 當您在方法內部編寫應用程序邏輯時,這很有幫助,因為您可以確保方法參數不會為`null`。 因此您不會提出不必要的假設和主張。 #### 3.9 在“安全”的非空字符串上調用`String.equals(String)` 代替在下面的代碼中編寫的字符串比較 ```java public class SampleNPE { public void demoEqualData(String param) { if (param.equals("check me")) { // some code } } } ``` 像這樣寫上面的代碼。 即使參數作為`null`傳遞,這也不會引起 NPE。 ```java public class SampleNPE { public void demoEqualData(String param) { if ("check me".equals(param)) // Do like this { // some code } } } ``` ## 4\. 可用的`NullPointerException`安全操作 #### 4.1 實例運算符 `instanceof`運算符是 NPE 安全的。 因此,`instanceof null`總是返回`false`。 它不會導致`NullPointerException`。 如果您記住這一事實,則可以消除混亂的條件代碼。 ```java // Unnecessary code if (data != null &amp;&amp; data instanceof InterestingData) { } // Less code. Better!! if (data instanceof InterestingData) { } ``` #### 4.2 訪問類的靜態成員 如果您要處理靜態變量或靜態方法,則即使您的引用變量指向`null`,也不會獲得`null`指針異常,因為靜態變量和方法調用是在編譯時根據類名綁定的,并且與對象無關 ```java MyObject obj = null; String attrib = obj.staticAttribute; //no NullPointerException because staticAttribute is static variable defined in class MyObject ``` 如果您知道更多這樣的語言構造,當遇到`null`時也不會失敗,請告訴我。 ## 5\. 如果必須在某些地方允許`NullPointerException`怎么辦 《Effective Java》中的 ***Joshua bloch*** 說:“可以說,所有錯誤的方法調用都可以歸結為非法參數或非法狀態,但是其他異常通常用于某些類型的非法參數和狀態。 如果調用者在某個參數中傳遞了`null`,該參數禁止使用`null`值,則約定將拋出`NullPointerException`而不是`IllegalArgumentException`。” 因此,如果必須在代碼中的某些位置允許`NullPointerException`,則請確保**使其具有更多信息,然后通常是這樣**。 看下面的例子: ```java package com.howtodoinjava.demo.npe; public class SampleNPE { public static void main(String[] args) { // call one method at a time doSomething(null); doSomethingElse(null); } private static String doSomething(final String param) { System.out.println(param.toString()); return "I am done !!"; } private static String doSomethingElse(final String param) { if (param == null) { throw new NullPointerException( " :: Parameter 'param' was null inside method 'doSomething'."); } System.out.println(param.toString()); return "I am done !!"; } } ``` 這兩個方法調用的輸出是這樣的: ```java Exception in thread "main" java.lang.NullPointerException at com.howtodoinjava.demo.npe.SampleNPE.doSomething(SampleNPE.java:14) at com.howtodoinjava.demo.npe.SampleNPE.main(SampleNPE.java:8) Exception in thread "main" java.lang.NullPointerException:? :: Parameter 'param' was null inside method 'doSomething'. at com.howtodoinjava.demo.npe.SampleNPE.doSomethingElse(SampleNPE.java:21) at com.howtodoinjava.demo.npe.SampleNPE.main(SampleNPE.java:8) ``` 顯然,第二個棧跟蹤更有用,并且使調試容易。 將來使用。 到目前為止,我對`NullPointerException`的了解已完成。 如果您知道有關該主題的其他觀點,請與我們所有人分享! 學習愉快!
                  <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>

                              哎呀哎呀视频在线观看