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 方法