当我在写程序中出现一个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
结果说明我的理解是对的。