Java中出现了一个不知原因的NullPointerException

时间:2023-01-04 15:42:59

当我在写程序中出现一个excption。百思不得解,然后我就写了一个小程序测试。程序是这样的时候:

public class HHH {
    private int[] a;

    public HHH() {
        int[] a = new int[10];
    }

    public void show() {
        System.out.println(a.length);
    }

    public static void main ( String[] args ) {
        HHH h = new HHH();
        h.show();
    }
}

程序会报错!!!

输出结果为: 
Exception in thread “main” java.lang.NullPointerException 
at test.HHH.show(HHH.java:21) 
at test.HHH.main(HHH.java:17)

从结果看在构造方法里的那个输出语句是对的,而在show()那个方法里的输出语句怎么就错了呢。顿时日了狗,为啥会出错。

然后试了好多次改成这样的:

public class HHH {
    private int[] a;

    public HHH() {
        a = new int[10];
    }

    public void show() {
        System.out.println(a.length);
    }

    public static void main ( String[] args ) {
        HHH h = new HHH();
        h.show();
    }
}

结果反而不报错了。原来是在构造方法里面再次对数组a声明了所以报错了。 
那么为什么是这样呢?

我的理解是,(private int[] a;)这里数组a在方法外声明,是一个全局变量,是所有类中所有方法可以调用的,也就是在其他没有特殊声明的方法用到数组a时,都是这个数组。 
而第一种代码在构造方法里再次对数组a声明并赋值(int[] a = new int[10];),这时在这个构造方法里的a是个局部变量,也就是在构造函数里对数组a的所有赋值和操作都是对这个局部变量操作。这样当show()方法挑用a.length的时候,全局变量还是声明的时候的那个全局变量,连初始化都没有做,当然会报错。 
第二种没有报错,因为构造函数没有重新声明数组a,只是初始化了数组,所以构造函数中对数组a的操作都是对方法外声明的全局变量的操作。当show()调用a.length时,这里的数组已经被构造函数初始化了,所以没出现空指针异常。

所以为了验证我的理解,我把方法外的那个数组也初始化一下,并初始化成不一样的长度,看看结果。

public class HHH {
    private int[] a = new int[5];

    public HHH() {
        int[] a = new int[10];
        System.out.println(a.length);
    }

    public static void main ( String[] args ) {
        HHH h = new HHH();
        h.show();
    }

    public void show() {
        System.out.println(a.length);
    }
}

输出结果是: 
10 
5

结果说明我的理解是对的。