- 先来看一下JDK1.6的API:
NullPointerException (Java Platform SE 6) public class NullPointerException extends RuntimeExceptionnull
当应用程序试图在须要对象的地方使用时,抛出该异常。这种状况包括:html
* 调用 null 对象的实例方法。 * 访问或修改 null 对象的字段。 * 将 null 做为一个数组,得到其长度。 * 将 null 做为一个数组,访问或修改其时间片。 * 将 null 做为 Throwable 值抛出。
应用程序应该抛出该类的实例,指示其余对 null 对象的非法使用。java
由以上说明能够看出,最主要的缘由就是调用的对象是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,不会报异常。
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 方法测试
详情连接this