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

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

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

爲何咱們須要空值?

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


例如,最多建立一個類實例的示例方法是將其全部構造函數聲明爲private,而後建立一個返回該類的惟一實例的公共方法:

TestSingleton.java: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()); } }

 

在這個例子中,咱們聲明瞭一個Singleton類的靜態實例。該實例在該getInstance方法內最多初始化一次。注意使用null啓用惟一實例建立的值。

如何避免NullPointerException程序員

爲了不這種狀況NullPointerException,請確保在使用它們以前,全部對象都已正確初始化。注意,當你聲明一個引用變量時,你真的建立了一個指向對象的指針。在向對象請求方法或字段以前,您必須驗證指針是否爲空。設計模式

另外,若是引起異常,請使用駐留在異常堆棧跟蹤中的信息。執行的堆棧跟蹤由JVM提供,以啓用應用程序的調試。找到捕獲異常的方法和行,而後肯定哪一個引用等於在特定行中爲null。數組

在本節的其他部分中,咱們將介紹一些處理上述例外的技術。可是,它們並無消除這個問題,程序員在編寫應用程序時應該當心。安全

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

1 String str = null; 2 if(str.equals(「Test」)){ 3      / *這裏的代碼將不會被觸發,由於會拋出異常。* /
4 }

上面的代碼片斷會拋出一個NullPointerException。可是,若是咱們從文字中調用方法,那麼執行流程一般會繼續:dom

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

2.檢查方法的參數
在執行你本身的方法的主體以前,必定要檢查它的參數爲空值。只有在正確檢查了參數後,才繼續執行該方法。不然,您能夠拋出一個IllegalArgumentException並通知調用方法傳遞的參數有問題。函數

例如:工具

1 public static int getLength(String s){ 2      若是(s == null3  拋出新的IllegalArgumentException(「參數不能爲空」); 4 
5      return s.length(); 6 }

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

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

4.使用三元運算符
該ternary操做是很是有用的,能夠幫助咱們避免了NullPointerException。運營商的形式是:

1 布爾表達式?value1:value2;

首先,評估布爾表達式。若是表達式爲true,則返回value1,不然返回value2。咱們可使用ternary運算符來處理空指針,以下所示:

1 String message =(str == null)?"":str.substring(0,10);

若是str引用爲空,則消息變量將爲空。不然,若是str指向實際數據,則消息將檢索它的前10個字符。

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

Example.java

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

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

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

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

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

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

在上面的代碼片斷中,咱們不檢查密鑰是否真的存在於內部Map,所以返回的值能夠是null。最安全的方法以下:

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

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

9.使用斷言
斷言在測試代碼時很是有用,而且能夠被使用,以免執行代碼片段,從而致使錯誤NullPointerException。Java斷言是用assert關鍵字實現的,並拋出一個AssertionError。

請注意,您必須顯式啓用JVM的斷言標誌,方法是使用–ea參數執行該標誌。不然,斷言將被徹底忽略。

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

1 public static int getLength(String s){ 2      / *確保String不爲null。* / 
3      assert(s!= null); 4 
5      return s.length(); 6 }

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

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

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

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

##現有的NullPointerException安全方法

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

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

TestStatic.java:

 1 class SampleClass {  2 
 3      public static void printMessage(){  4  System.out.println(「Hello Java Geeks!」);  5  }  6 }  7 
 8 public class TestStatic {  9      public static void main(String [] args){ 10           SampleClass sc = null; 11  sc.printMessage(); 12  } 13 }

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

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

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

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

1 Not an instance of the String class!

 

這是一篇關於如何處理Java的教程NullPointerException。轉載

相關文章
相關標籤/搜索