你真的了解Java中的空指针异常吗?

一、什么是空指针异常?

我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析。空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(静态的除外),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常。

public class Demo {
 2     private int a=6;
 3     private int b=8;
 4     public static void main(String[] args) {
 5         
 6         Demo d1 = new Demo();
 7         Demo d2 = null; 
 8         System.out.println(d1.a);
 9         System.out.println(d2.a);
10         System.out.println(d2.c());
11     }
12     public String c(){
13         return "调用成功!";
14     }
15 }

我们分析上面这段示例代码,在Demo类中,有两个成员变量ab,和一个方法c()。然后在main()方法中,我们创建了两个对象d1d2,其中d1指向通过构造方法实例出的Demo对象,而d2只是声明,并指向了空,并没有指向实际的对象。调试的时候,第一条输出语句是可以通过编译的,而执行到第二条输出语句的时候,由于空指针调用了不属于它的a,程序终止,报告空指针异常。同样,注释第二条输出语句,程序在执行到第三条输出语句的时候,由于调用了不属于它的c()方法,会出现一样的错误。

二、为什么会出现空指针异常

1:字符串常量没有初始化

 String s = null;   //对象s为空(null)
 int length = s.length();//发生空指针异常   

2:接口类型的对象没有用具体的类初始化

List it;    //会报异常 
List it = new ArrayList();    //正确写法

3:没有去判断变量是否为空,就直接使用

 写程序时严谨些,尽量避免不判断变量是否为空,就直接使用,
//例如在拿该变量与一个值比较时,要么先做好该异常的处理如: 
if (str == null) {   
	System.out.println("字符为空!");
} 
 当然也可以将这个值写在前面进行比较的,
 //例如,判断一个String的实例s是否等于“a”,
 不要写成s.equals("a"),这样写容易抛出NullPointerException,
 而写成"a".equals(s)就可以避免这个问题。
 总之对变量先进行判断是否为空后再进行操作比较好。

4:一般的类型的返回值为null
尽量避免返回null,方法的返回值不要定义成为一般的类型,而是用数组。这样如果想要返回null的时候,就返回一个没有元素的数组。就能避免许多不必要的NullPointerException,使用NullObject返回代替返回null确是一种不错的选择。

三、怎么解决空指针异常?

空指针的解决办法:
重点关注报错发生的所在行,通过空指针异常产生的两条主要原因诊断具体的错误。同时为了避免空指针的发生,最好在做判断处理时将“null”或者空值放于 设定的值之前。

常见空指针异常的简要分析:
(1)空指针错误
Java中的8种基本数据类型,变量的值可以有其默认值,假如没有对其正常赋值,java虚拟机是不能正确编译通过的,因此使用基本的Java数据类型一般是不会引起空指针异常的。实际开发中,大多数的空指针异常主要与对象的操作相关。
下面列出可能发生空指针异常的几种情况及相应解决方案:

代码段1:

System.out.println(request.getParameter("username"));

分析:
代码段1的功能十分简单,就是输出用户输入"username"的值。
说明:
看上去,上面的语句找不出什么语法错误,而且在大多数情况下也遇不到什么问题。但是,如果某个用户在输入数据时并没有提供表单域"username" 的值,或通过某种途径绕过表单直接输入时,此request.getParameter("username")的值为空(注意不是空字符串,是空对象 null。),out对象的println方法是无法直接对空对象操作的,因此代码段1所在的JSP页面将会抛出"Java.lang.NullPointerException"异常。
而且即使对象可能为空时,也调用Java.lang.ObjectObject对象本身的一些方法如toString()equal(Object obj)等操作。

代码段2:

   String userName = request.getParameter("username"); 
  if (userName.equals("root")) 
  {....} 

分析
代码段2的功能是检测用户提供的用户名,如果是用户名称为"root"的用户时,就执行一些特别的操作。

说明
在代码段2中,如果有用户没有提供表单域"username"的值时,字符串对象
userNamenull值,不能将一个null的对象与另一个对象直接比较,同样,代码段2所在的JSP页面就会抛空指针错误。
小技巧
如果要把某个方法的返回值与常量做比较,把常量放在前面,可以避免调用null对象的equals方法。譬如:
If ("root".equals(userName))   {....}
即使userName对象返回了null对象,这里也不会有空指针异常,可以照常运转。

代码段3:

String userName = session.getAttribute("session.username").toString(); 

分析:
代码段3的功能是将sessionsession.username的值取出,并将该值赋给字符串对象userName
说明:
在一般情况下,如果在用户已经进行某个会话,则不会出现什么问题;但是,如果此时应用服务器重新启动,而用户还没有重新登录,(也可能是用户关闭浏览器,但是仍打开原来的页面。)那么,此时该session的值就会失效,同时导致session中的session.username的值为空。对一个为 null的对象的直接执行toString()操作,就会导致系统抛出空指针异常。

代码段4:

public static void main(String args[]){
       Person p=null;
       p.setName("张三");
       System.out.println(p.getName());
}

分析:
声明一个Person对象,并打印出该对象的中的Name名字。
说明:
这个时候你的p就出现空指针异常,因为你只是声明了这个Person类型的对象并没有创建对象,所以它的堆里面没有地址引用,切忌要用对象调用方法的时候一定要先创建对象

PS:当然实际开发中还会有很多场景下会出现空指针异常,这里就不一一列举了

这篇文章是参考了多位大佬的文章进行了一个自我总结,在此感谢各位大佬的知识分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值