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

详情链接

posted on 2018-05-17 15:21  一只阿木木  阅读(1988)  评论(0编辑  收藏  举报