天涯明月刀ol|天涯明月刀迅雷下载
  1. 當前所在位置:
  2. 首頁
  3. 打魚捕魚

java.lang.NullPointerException - 如何處理空指針異常

2018-12-26 admin

當應用程序試圖null在需要對象的情況下使用時拋出。這些包括:


調用null對象的實例方法。
訪問或修改null對象的字段。
把長度null當作一個數組。
像訪問或修改null陣列一樣訪問或修改插槽。
投擲null就好像它是一個Throwable 價值。
應用程序應該拋出此類的實例來指示null對象的其他非法使用。 
NullPointerException對象可以由虛擬機構造,就像抑制被禁用和/或堆棧跟蹤不可寫一樣。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

為什么我們需要空值?


如前所述,nullJava是一種特殊的值。
它在編碼某些設計模式(如空對象模式和單例模式)時非常有用。
空對象模式提供了一個對象作為缺少給定類型對象的代理。
Singleton模式確保只創建一個類的一個實例,并且旨在提供對象的全局訪問點。
  • 1
  • 2
  • 3
  • 4

例如,最多創建一個類實例的示例方法是將其所有構造函數聲明為private,然后創建一個返回該類的唯一實例的公共方法:

TestSingleton.java:

import java.util.UUID;

class Singleton {

     private static Singleton single = null;
     private String ID = null;

     private Singleton() {
          /* Make it private, in order to prevent the creation of new instances of
           * the Singleton class. */

          ID = UUID.randomUUID().toString(); // Create a random ID.
     }

     public static Singleton getInstance() {
          if (single == null)
               single = new Singleton();

          return single;
     }

     public String getID() {
          return this.ID;
     }
}

public class TestSingleton {
     public static void main(String[] args) {
          Singleton s = Singleton.getInstance();
          System.out.println(s.getID());
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在這個例子中,我們聲明了一個Singleton類的靜態實例。該實例在該getInstance方法內最多初始化一次。注意使用null啟用唯一實例創建的值。

如何避免NullPointerException

為了避免這種情況NullPointerException,請確保在使用它們之前,所有對象都已正確初始化。注意,當你聲明一個引用變量時,你真的創建了一個指向對象的指針。在向對象請求方法或字段之前,您必須驗證指針是否為空。

另外,如果引發異常,請使用駐留在異常堆棧跟蹤中的信息。執行的堆棧跟蹤由JVM提供,以啟用應用程序的調試。找到捕獲異常的方法和行,然后確定哪個引用等于在特定行中為null。

在本節的其余部分中,我們將介紹一些處理上述例外的技術。但是,它們并沒有消除這個問題,程序員在編寫應用程序時應該小心。

1.字符串與文字的比較  應用程序執行代碼中的一個非常常見的情況涉及字符串變量和文字之間的比較。文字可以是一個字符串或Enum的元素。不要從空對象調用方法,而應考慮從文字中調用它。例如,觀察以下情況:

String str = null;
if(str.equals(“Test”)){
     / *這里的代碼將不會被觸發,因為會拋出異常。* /
}
  • 1
  • 2
  • 3
  • 4

上面的代碼片段會拋出一個NullPointerException。但是,如果我們從文字中調用方法,那么執行流程通常會繼續:

String str = null;
if(“Test”.equals(str)){
     / *正確的用例。不會拋出異常。* /
}
  • 1
  • 2
  • 3
  • 4

2.檢查方法的參數  在執行你自己的方法的主體之前,一定要檢查它的參數為空值。只有在正確檢查了參數后,才繼續執行該方法。否則,您可以拋出一個IllegalArgumentException并通知調用方法傳遞的參數有問題。

例如:

public static int getLength(String s){
     如果(s == null)
          拋出新的IllegalArgumentException(“參數不能為空”);

     return s.length();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.優先使用String.valueOf()方法代替toString()  當您的應用程序代碼需要對象的字符串表示形式時,請避免使用該對象的toString方法。如果你的對象的引用等于null,NullPointerException則會拋出a。

相反,考慮使用靜態String.valueOf方法,該方法不會拋出任何異常并打印”null”,以防函數的參數等于null。

4.使用三元運算符  該ternary操作是非常有用的,可以幫助我們避免了NullPointerException。運營商的形式是:

布爾表達式?value1:value2;
  • 1

首先,評估布爾表達式。如果表達式為true,則返回value1,否則返回value2。我們可以使用ternary運算符來處理空指針,如下所示:

String message =(str == null)?""str.substring(010);
  • 1

如果str引用為空,則消息變量將為空。否則,如果str指向實際數據,則消息將檢索它的前10個字符。

5.創建返回空集合而不是null的方法  一個非常好的技術是創建返回一個空集合的方法,而不是一個null值。你的應用程序的代碼可以遍歷空集合并使用它的方法和字段,而不會拋出一個NullPointerException。例如:

Example.java

public class Example {
     private static List<Integer> numbers = null;

     public static List<Integer> getList() {
          if (numbers == null)
               return Collections.emptyList();
          else
               return numbers;
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6.使用Apache的StringUtils類  Apache的Commons Lang是一個為java.langAPI 提供幫助工具的庫,比如字符串操作方法。提供字符串操作的示例類是StringUtils.java,它null靜靜地處理輸入字符串。

你可以使用StringUtils.isNotEmpty, StringUtils.IsEmpty和StringUtils.equals方法,以避免NullPointerException。例如:

if(StringUtils.isNotEmpty(str)){ 
     System.out.println(str.toString()); 
}
  • 1
  • 2
  • 3

7.使用contains(),containsKey(),containsValue()方法  如果您的應用程序代碼使用集合,例如Maps考慮使用包含containsKey和containsValue方法。例如,在地圖中驗證其存在之后,檢索特定鍵的值:

Map <String,String> map = ... 
... 
String key = ... 
String value = map.get(key); 
的System.out.println(value.toString()); //如果值為null,則會拋出異常。
  • 1
  • 2
  • 3
  • 4
  • 5

在上面的代碼片段中,我們不檢查密鑰是否真的存在于內部Map,因此返回的值可以是null。最安全的方法如下:

Map <String,String> map = ... 
... 
String key = ... 
if(map.containsKey(key)){ 
     String value = map.get(key); 
     的System.out.println(value.toString()); //不會拋出異常。
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

8.檢查外部方法的返回值  在實踐中使用外部庫是很常見的。這些庫包含返回引用的方法。確保返回的參考不是null。另外,請考慮閱讀該方法的Javadoc,以便更好地理解其功能和返回值。

9.使用斷言  斷言在測試代碼時非常有用,并且可以被使用,以避免執行代碼片斷,從而導致錯誤NullPointerException。Java斷言是用assert關鍵字實現的,并拋出一個AssertionError。

請注意,您必須顯式啟用JVM的斷言標志,方法是使用–ea參數執行該標志。否則,斷言將被完全忽略。

使用Java斷言的示例示例如下:

public static int getLength(String s){ 
     / *確保String不為null。* / 
     assert(s!= null); 

     return s.length(); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果您執行上面的代碼段并傳遞一個空參數getLength,則會出現以下錯誤消息:

Exception in thread "main" java.lang.AssertionError
  • 1

最后,您可以使用測試框架Assert提供的類jUnit。

10.單元測試  在測試代??碼的功能和正確性時,單元測試可能非常有用。花一些時間編寫一些測試用例,驗證NullPointerException應用程序的代碼是否經歷了特定的執行流程,否則將引發no 。

現有的NullPointerException安全方法

1.訪問類的靜態成員或方法  當你的代碼試圖訪問靜態變量或類的方法時,即使對象的引用等于null,JVM也不會拋出一個NullPointerException。這是由于Java編譯器在編譯過程中將靜態方法和字段存儲在特殊位置。因此,靜態字段和方法不與對象相關聯,而與類的名稱相關聯。

例如,下面的代碼不會拋出NullPointerException:

TestStatic.java:

class SampleClass { 

     public static void printMessage(){ 
          System.out.println(“Hello Java Geeks!”); 
     } 
} 

public class TestStatic { 
     public static void main(String [] args){ 
          SampleClass sc = null; 
          sc.printMessage(); 
     } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注意,盡管SampleClass等于的實例null將會被正確執行。但是,對于靜態方法或字段,最好以靜態方式訪問它們,比如SampleClass.printMessage()。

2.運營商的instanceof  instanceof即使對象的引用等于,也可以使用該運算符null。在instanceof操作時,參考值等于為null,不拋出一個返回false NullPointerException。例如,考慮下面的代碼片段:

String str = null;
if(str instanceof String)
     System.out.println("It's an instance of the String class!");
else
     System.out.println("Not an instance of the String class!");
  • 1
  • 2
  • 3
  • 4
  • 5

正如預期的那樣,執行的結果是:

Not an instance of the String class!
  • 1

這是一篇關于如何處理Java的教程NullPointerException。

腳注生成一個腳注[^ footnote]。[^ footnote]:這里是腳注內容。使用MathJax渲染* LaTex *數學公式,詳見[math.stackexchange.com] [1] 。\行內公式,數學公式,數學公式,數學公式, Gamman=n1 quad foralln in mathbbN .-塊級公式: x = \ dfrac { - b \ pm \ sqrt {b ^ 2 - 4ac}} {2a

  } $$更多LaTex語法請參考[這兒] [3]。### UML圖:可以渲染序列圖:```sequence張三 - >李四:嘿,小四兒,寫博客了沒?注意的李四權:李四愣了一下,說:李四 - >張三:忙得吐血,哪有時間寫``或流程圖:````流ST =>啟動:開始E =>端:結束OP =>操作:我的操作COND =>條件:確認?ST-> OP-> CONDCOND(是) - >電子COND(無) - >運算``` - 關于**序列圖* *語法,參考[這兒] [4], - 關于**流程圖**語法,參考[這兒] [5]。
  • 1

離線寫博客即使用戶在沒有網絡的情況下,也可以通過本編輯器離線寫博客(直接在曾經使用過的瀏覽器中輸入[write.blog.csdn.net/mdeditor](HTTP:// write.blog.csdn.net/mdeditor)即可。* Markdown編輯器使用瀏覽器離線存儲將內容保存在本地。用戶寫博客的過程中,內容實時保存在瀏覽器緩存中,在用戶關閉瀏覽器或者其它異常情況下,內容不會丟失。用戶再次打開瀏覽器時,會顯示上次用戶正在編輯的沒有發表的內容。博客發表后,本地緩存將被刪除。用戶可以選擇 把正在寫的博客保存到服務器草稿箱,即使換換瀏覽器或者清除緩存,內容也不會丟失。> 注意:雖然瀏覽器存儲大部分時候都比較可靠,但為了您的數據安全,在聯網后,請務必及時發表或者保存到服務器草草箱*

瀏覽器兼容1.目前,本編輯器對鉻瀏覽器支持最為完整。建議大家使用較新版本的鉻.3.IE9以下不支持4.IE9,10,11存在以下問題1.不支持離線功能1.IE9不支持文件導入1.IE10不支持拖拽文件導入——- 

捕魚駕到 天涯明月刀ol