前言

我最近在做一个小小小项目——快递柜管理,期间遇到了一个会导致抛出空指针异常的小问题,说它是小问题,是因为真的只是在写代码的时候注意一下就好了,但是这里还要写一个博客,就是为了剖析这个问题,然后给自己做个备忘,也给看博客的各位提个醒。

1、知识补充:null

关于null,你不得不知道的几件事:

1、null是Java中的关键字,像public、static、final。它是大小写敏感的,你不能将null写成Null或NULL,编译器将不能识别它们然后报错。

2、就像每种原始类型都有默认值一样,如int默认值为0,boolean的默认值为false,null是任何引用类型的默认值不严格的说是所有object类型的默认值

3、null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型。

4、null可以赋值给引用变量,你不能将null赋给基本类型变量,例如int、double、float、boolean。如果你那样做了,编译器将会报错。

5、任何含有null值的包装类在Java拆箱生成基本数据类型时候都会抛出一个空指针异常。(例如Integer拆箱成int时)

6、如果使用了带有null值的引用类型变量,instanceof操作将会返回false。(instanceof:用来在运行时指出对象是否是特定类的一个实例,例如:Integer num = null,那么,调用 num instanceof Integer时会返回false)

7、不能调用非静态方法来使用一个值为null的引用类型变量,它将会抛出空指针异常;可以使用静态方法来使用一个值为null的引用类型变量,因为静态方法使用静态绑定,不会抛出空指针异常。

8、你可以使用 == 或者!=操作来比较null值,但是不能使用其他算法或者逻辑操作,例如小于或者大于。跟SQL不一样,在Java中null ==null将返回true。

2、剖析案例

什么是空指针呢?我的理解是:向一个可能不存在的对象去索取它的属性或者让它执行方法是不可能成功的,你非要逼程序这么做就会出现空指针。
举个很形象的例子 你家没有叫张三的这个人,我去你家说你家的张三欠我一个亿,你会给我不哈哈哈哈

接下来就举个简单例子 来剖析这次的主题内容。

假设我们现在有一个类,例如String,对于如下代码:

public class Demo_1_1 {
    public static void main(String[] args) {
        String str = null;
        if(str.equals("爱摸鱼的TT~")){
            System.out.println("Nice");
        }else{
            System.out.println("Oh,no");
        }
    }
}

运行结果:

java 文件名 Java 文件名equals失效_String


看结果可知,编译器会抛出空指针异常。

而如果我们把第四行的条件判断改为:

if("爱摸鱼的TT~".equals(str))

就不会抛出空指针异常(因为String的equals方法没有被static修饰),编译器就会顺着代码判断得出下面结果:

java 文件名 Java 文件名equals失效_null_02


那为什么互换下操作数,结果变化就如此大呢?就得让我们看看String类的equals方法的源码:

java 文件名 Java 文件名equals失效_空指针异常_03


源码我看了一下,也明白,但是在源码中如果anObject为空的时候,就不会出现空指针异常吗 ?

后来经过一番研究后,我得出的结论是这样的:

问题是出现调用equals方法上了,如果一个初值可能为空的对象实例,调用equals方法时,要么先判断它是不是空,不是空才比较;要么一定要遵循 “常量”.equals(变量) 或者 后输入的.equals(之前的)。这样就可以尽量避免空指针错误,平时多注意,养成习惯,防止日后埋下隐患。