JDK1.6 Java.lang.Null.Pointer.Exception


  • 先來看一下JDK1.6的API:
NullPointerException (Java Platform SE 6)
public class NullPointerException extends RuntimeExceptionnull

 

當應用程序試圖在需要對象的地方使用時,拋出該異常。這種情況包括:

* 調用 null 對象的實例方法。 * 訪問或修改 null 對象的字段。 * null 作為一個數組,獲得其長度。 * null 作為一個數組,訪問或修改其時間片。 * null 作為 Throwable 值拋出。

應用程序應該拋出該類的實例,指示其他對 null 對象的非法使用。

由以上說明可以看出,最主要的原因就是調用的對象是NULL

  • 經常會出現空指針的情況有:
(1)字符比較
    String str1 = someclass.getSomeString();
    if(str1.equalsIgnoreCase("YES"))
    {
      //do something
    }
    else if(str1.equalsIgnoreCase("NO"))
    {
     //do something else
    }
    (2)讀取配置文件
       props.getProperty("somekey");
    (3)從MAP取值
        map.get("key");
    (4)從Session取值
        String userName = request.getSession().getAttribute("userName"); 

 

等等,這里發生NullPointerException的機會非常大,而且運行情況往往和用戶輸入的數據有關,所以不容易被發現. 如何避免空指針異常?最主要的是養成一個好的編碼習慣,在對對象進行調用方法、比較等等操作時,要判斷一下對象有沒有可能會是NULL,提前進行處理。

 

str1.equalsIgnoreCase("YES"); 而應該寫成這樣:
"YES".equalsIgnoreCase(str1), 這樣就可以避免空指針異常。

 

這兩種寫法的差異,主要是程序對對象的操作是先判斷再執行,就是先判斷對象是否存在,然后再去執行其它操作。第一種方式在判斷str1的時候,如果str1是null,這是程序肯定會拋出異常,而第二種就OK,不會報異常。
  • 使用Java語言開發應用程序不管是J2SE還是J2EE的,沒有幾個開發者沒經歷空指針異常 (NullPointerException)錯誤的,作為一個runtime Exception最為常見的幾種原因是:
 1 1.         對象未初始化而直接引用對象值或者方法到的,代碼示例:
 2 package com.fish.codesample;
 3 public class JavaNullSample {
 4    
 5     private String name;
 6     public JavaNullSample() {
 7     }
 8     public String getName() {
 9        return name;
10     }
11     public static void main(String[] args) {
12        new JavaNullSample().getName().length();
13     }
14 }
15 2.         對象引用已經不存在或者被JDBC關閉
16        一個經典的例子是JDBC connection已經關閉,ResultSet對象仍然被使用中,這個時候NullPointerException就被拋出。
17  
18 3.         違反某些Java容器的限制,讀寫Null 值
19 這個方面首推的就java.util.HashTable,它不接受Null 作為Key或者Value,如果試圖用Null作為Key去讀取HashTable將會得到NullPointerException,代碼示例:
20 Hashtable<String,String> table = new Hashtable<String,String>();
21 String tKey = null;
22 // the following codes always throw NullPointerException
23 tKey = table.get(null);
24 table.put(tKey, null);
25 當使用TreeMap/TreeSet的時候,一定確保所有對象的屬性的值不為Null,否則在調用get/set方法時候會拋出NullPointerException, 代碼示例:
26        TreeMap<Person, String> tMap = new TreeMap<Person, String>();
27        Person personer1 = new JavaTreeMap(). new Person();
28        Person personer2 = new JavaTreeMap(). new Person();
29        personer1.setName("fish");
30        tMap.put(personer1, "person1");
31        tMap.put(personer2, "person2"); // throw NullPointerException
32  
33  
34 還有幾種相對比較難的Java NullPointerException異常
35 1.         java Swing/AWT NullPointerException
36 1)        最常見的錯誤時忘記初始化某個Swing組件,當調用JFrame.getContentPane().add()方法時導致NullPointerException
37 2)        當調用JFrame.pack()的時候拋出NullPointerException,最可能的一個原因是JFrame的容器中的Swing組件可能被開發者自己重寫而導致不適用pack().
38 3)        Java JDK6與JDK4的Swing監聽機制已經有很大的不同,如果在初始化的時候觸發Listener導致執行listener的某些方很可能導致拋出NullPointerException
39 4)        某些Java2D/Java3D的組件可能導致NullPointerException
40  
41 2.         Socket連接丟失導致IO流的Java NullPointerException
42  
43 3.         資源文件加載錯誤導致的NullPointerException,最常見的代碼示例如下:
44        InputStream in =this.getClass().getResourceAsStream(PropertiesName); 
45        props.load(in);  // throw NullPointerException if xml/property files missing
46  
47 4.         多線程導致的NullPointerException
48        這種原因導致的NullPointerException一般很難被發現,特別是在大型和復雜的系統中
49 而且一段時間內業很難被重現,修復這樣的bug成本很高,不修復這樣的bug代價很大,意味着用戶可能失去對該產品的信任。

 

[后記:Java NullPointerException做為Java Runtime 異常,在開發中減少這樣錯誤的發生就是對代碼完成Junit的單元測試,對於一些重要的代碼要提高code review的次數從而提高代碼質量,增加產品的可靠性。]

  • 給向往遠方的你: 沒有比腳更長的路,沒有比人更高的山。 --汪國真《山高路遠》

 

 

 

如何避免null 值呢, JDK 1.8 中引入了Optional 方法

詳情鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM