java中的空指针异常情况以及解决⽅案
⽬录
概述
问题描述
第⼀种
第⼆种
第三种
问题定位
Java空指针异常的若⼲解决⽅案
存在NullPointerException的安全⽅法
getattribute方法返回类型如何避免
java空指针异常:java.lang.NullPointException
⼀.什么是java空指针异常
⼆.如何解决
概述
出现空指针异常,常常是因为我们调⽤的对象是空的⽽抛出的异常。
问题描述
第⼀种
out.Parameter("username"));
如果request⾥⾯并没有username的值,这时⽆法对空对象进⾏操作的,就会抛出异常。
第⼆种
String userName = Parameter("username");
If (userName.equals("root"))
{....}
如果没有username值,或者username为null时,是不能将⼀个为null的对象与另外⼀个对象进⾏⽐较的。
If ("root".equals(user Name))
{....}
如果返回值与常量进⾏⽐较时,就可以避免调⽤null对象的equals⽅法。不会抛出异常。
第三种
假设有⼀个student类,有属性name。
Student a;
String b = a.name;
这个时候就会报错,因为a为空的,解决办法就是让a指向⼀个对象,Student a = new Student();
问题定位
对于⽇志中的报错信息,在java中抛出异常是从内往外,因此只需要重点关注第⼀⾏报错信息,下⾯的报错都是由于⼀层层传递调⽤该⽅法导致。
Java空指针异常的若⼲解决⽅案
Java中任何对象都可以为空,我们可以使⽤若⼲种⽅法来避免产⽣这类异常。⽐如我们传统的空值检测,编程规范,以及使⽤java中各种⼯具类。
(1)最常⽤的⼀种就是直接对对象进⾏判断
⽐如if(Object == null)来对所有⽤到的对象进⾏判断,这个对象也就是我们常⽤的函数参数,返回值,以及类实例的成员变量
等。当我们检测到null值时,我们可以异常的类型抛出更具有针对性的异常类型,再附加上我们⾃⼰加的消息内容。我们也可以直接使⽤⼀些库函数来简化代码:
Object checkData = quireNoNull(resultMessage,"The resultMessage must not be null")
如果我们使⽤过Lombok⼯具的话,⾥⾯有⼀个@NotNull注解,就是指被注释的元素不能为空,就会⾃定检测。
(2)第⼆种⽅法就是遵守编程规范,可以减少⼀定的空指针异常的发⽣。
Strings.isNullOrEmpty(str);
CollectionUtils.isEmpty(collection);
StringUtils.isEmpty(str);
if(object != null) {
} // 使⽤toString()这种⽅法的话,如果object为空的话,就会抛出异常
String.valueOf(object) //将Object转换为字符串,不管是否为null,不会抛出异常
如果返回是集合类型。⽽且是空的,不要返回null值,⽽是要返回⼀个空的集合,如果返回类型是对象的话,我们可以抛出异常。
public class Example {
private static List<Integer> numbers = null;
public static List<Integer> getList() {
if (numbers == null)
ptyList();
else
return numbers;
}
}
检查⼀个⽅法的参数,在执⾏⽅法之前,确保检查了参数是否null,当参数被适当检查后,⽅法会继续执⾏。否则抛出叫做llegalArgumentException的异常,并通知调⽤的⽅法传⼊的参数有误。
使⽤三元运算符,可以避免NullPointerException,形式如下:
boolean expression ? value1:value2;
存在NullPointerException的安全⽅法
第⼀种使⽤instanceof 操作符
即使对象的引⽤为null,instanceOf操作符可使⽤。当引⽤为null时,instanceof操作符返回false,⽽且不会抛出NullPointerException,⽐如:
String str = null;
if(str instanceof null) {
<(.......)
}
如何避免
确保所有对象在使⽤之前被初始化。
java空指针异常:java.lang.NullPointException
⼀.什么是java空指针异常
我们都知道java是没有指针的,这⾥说的"java指针"指的就是java的引⽤,我们不在这⾥讨论叫指针究竟合不合适,⽽只是针对这个异常本⾝进⾏分析。
空指针就是空引⽤,java空指针异常就是引⽤本⾝为空,却调⽤了⽅法,这个时候就会出现空指针异常。
可以理解,成员变量和⽅法是属于对象的(除去静态),在对象中才存在相对应的成员变量和⽅法,然后通过对象去调⽤这些成员变量和⽅法。
对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和⽅法,这个时候⽤它去调⽤某些属性和⽅法,当然会出现空指针异常。
public class Test {
private int a=1;
private int b=2;
public static void main(String[] args) {
// TODO Auto-generated method stub
Test t1 = new Test();
Test t2 = null;
System.out.println(t1.a);
System.out.println(t2.a);
System.out.println(t2.c());
}
public String c(){
return "123";
}
}
我们分析上⾯这段⽰例代码,在Test类中,有两个成员变量a和b,和⼀个⽅法c()。
然后在main()⽅法中,我们创建了两个对象t1和t2,其中t1指向通过构造⽅法实例出的Test对象,⽽t2只是声明,并指向了空,并没有指向实际的对象。
调试的时候,第⼀条输出语句是可以通过编译的,⽽执⾏到第⼆条输出语句的时候,由于空指针调⽤了不属于它的a,程序终⽌,报告空指针异常。
同样,注释第⼆条输出语句,程序在执⾏到第三条输出语句的时候,由于调⽤了不属于它的c()⽅法,会出现⼀样的错误。⼆.如何解决
对于每⼀个java程序员来说,⼏乎都避免不了遇到空指针异常,特别是经验不⾜的初学者。⽽且由于它的调试和查相对其它异常来说⽐较困难,常常需要花费很⼤的精⼒去解决它。
⾸先认识⼀下java中的null
null是Java中⼀个很重要的概念。null设计初衷是为了表⽰⼀些缺失的东西,例如缺失的⽤户、资源或其他东西。但是,⼀年后,令⼈头疼的空指针异常给Java程序员带来不少的骚扰。
null是java中的关键字,因此,它不能写成NULL,Null,只能是null。
null是所有引⽤类型的默认值,如果没有让⼀个引⽤指向⼀个实际存在的对象,它的默认值就是null。null本质上是⼀个值,这跟int的默认值是0,boolean的默认值是false⼀样。现在,我们通常都使⽤像eclipse等的集成开发环境进⾏开发,⼀般在定义变量的时候都会进⾏初始化(这也是写代码的⼀个良好的习惯),如果没有进⾏初始化,系统会进⾏提⽰。
报空指针异常的原因有以下⼏种:
1字符串变量未初始化;
2接⼝类型的对象没有⽤具体的类初始化,⽐如:
List it;会报错
List it = new ArrayList();则不会报错了
3当⼀个对象的值为空时,你没有判断为空的情况。你可以试着把下⾯的代码前加⼀⾏代码:
if(rb!=null && rb!="")
改成:
if(rb==null);
if(rb!==null&&rb!="") 或者if("").equals(rb))
空指针的解决办法:
重点关注报错发⽣的所在⾏,通过空指针异常产⽣的两条主要原因诊断具体的错误。同时为了避免空指针的发⽣,最好在做判断处理时将“null”或者空值放于设定的值之前。
常见空指针异常的简要分析:
(1)空指针错误
Java中的8种基本数据类型,变量的值可以有其默认值,加⼊没有对其正常赋值,java虚拟机是不能正确编译通过的,因此使⽤基本的Java数据类型⼀般是不会引起空指针异常的。实际开发中,⼤多数的空指针异常主要与对象的操作相关。
下⾯列出可能发⽣空指针异常的⼏种情况及相应解决⽅案:
代码段1:
out.Parameter("username"));
分析:代码段1的功能⼗分简单,就是输出⽤户输⼊"username"的值。
说明:看上去,上⾯的语句不出什么语法错误,⽽且在⼤多数情况下也遇不到什么问题。但是,如果某个⽤户在输⼊数据时并没有提供表单域"username" 的值,或通过某种途径绕过表单直接输⼊时,此Parameter("username")的值为空(注意不是空字符串,是空对象 null。),out对象的println⽅法是⽆法直接对空对象操作的,因此代码段1所在的JSP页⾯将会抛出 "Java.lang.NullPointerException"异常。⽽且即使对象可能为空时,也调⽤Java.lang.Object或 Object对象本⾝的⼀些⽅法如toString(), equal(Object obj)等操作。
代码段2:
String userName = Parameter("username");
If (userName.equals("root"))
{....}
分析:代码段2的功能是检测⽤户提供的⽤户名,如果是⽤户名称为"root"的⽤户时,就执⾏⼀些特别的操作。
说明:在代码段2中,如果有⽤户没有提供表单域"username"的值时,字符串对象userName为null值,不能够将⼀个null的对象与另⼀个对象直接⽐较,同样,代码段2所在的JSP页⾯就会抛空指针错误。
⼀个⼩技巧:如果要把某个⽅法的返回值与常量做⽐较,把常量放在前⾯,可以避免调⽤null对象的equals⽅法。譬如:
If ("root".equals(userName))
{....}
即使userName对象返回了null对象,这⾥也不会有空指针异常,可以照常运转。
代码段3:
String userName = Attribute("session.username").toString();
分析:代码段3的功能是将session中session.username的值取出,并将该值赋给字符串对象userName。
说明:在⼀般情况下,如果在⽤户已经进⾏某个会话,则不会出现什么问题;但是,如果此时应⽤服务
器重新启动,⽽⽤户还没有重新登录,(也可能是⽤户关闭浏览器,但是仍打开原来的页⾯。)那么,此时该session的值就会失效,同时导致session中的session.username的值为空。对⼀个为 null的对象的直接执⾏toString()操作,就会导致系统抛出空指针异常。
代码段4:
public static void main(String args[]){
Person p=null;
p.setName("张三");
System.out.Name());
}
分析:声明⼀个Person对象,并打印出该对象的中的Name名字。
说明:这个时候你的p就出现空指针异常,因为你只是声明了这个Person类型的对象并没有创建对象,所以它的堆⾥⾯没有地址引⽤,切忌你要⽤对象掉⽤⽅法的时候⼀定要创建对象。
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论