没有初始大小的字符串数组给出空指针异常

时间:2013-05-26 18:01:58

标签: java arrays nullpointerexception

我只是检查了一些OCJP问题,并在字符串数组初始化和异常期间遇到了这种差异。

案例1

try {
    String[][] b = new String[10][10]; // 1
    System.out.println(b[0][0]);       // 2
} catch (Exception e) {
    System.out.println("Exception during array 'b' initialization");
        e.printStackTrace();
}

案例2

try {
    String[][] a = new String[10][]; // 3
    System.out.println(a[0][0]);     // 4
} catch (Exception e) {
    System.out.println("Exception during array 'a' initialization");
    e.printStackTrace();
}

第2行不会抛出任何异常,而第4行会抛出空指针异常。 第2行确实将值输出为null

当指定数组的大小时,java的初始化默认值是否有差异?不是吗?

3 个答案:

答案 0 :(得分:5)

这将a的类型设置为数组数组:

String[][] a

写作时

String[][] a = new String[10][];

初始化外部数组,但不创建内部数组,因此a[0]null

写作时

String[][] b = new String[10][10];

运行时也会创建内部数组。它描述了here in the specification

  

在运行时,对数组创建表达式的求值表现为   如下:

     

如果没有维度表达式,那么必须有一个数组   初始化程序。

     

将使用提供的值初始化新分配的数组   通过§10.6中描述的数组初始化器。

     

数组初始值设定项的值将成为数组的值   创作表达。

     

否则,没有数组初始值设定项,并且:

     

首先,从左到右评估维度表达式。如果有的话   表达式评估突然完成,表达式为   它的权利没有被评估。

     

接下来,检查维度表达式的值。如果   任何DimExpr表达式的值小于零,然后是a   抛出NegativeArraySizeException。

     

接下来,为新阵列分配空间。如果没有足够的   空间分配数组,评估数组创建   表达式通过抛出OutOfMemoryError突然完成。

     

然后,如果出现单个DimExpr,则会创建一维数组   指定长度,并且数组的每个组件都是   初始化为其默认值(§4.12.5)。

     

否则,如果出现n个DimExpr表达式,则创建数组   有效地执行一组深度为n-1的嵌套循环来创建   隐含的数组数组。

     

多维数组不需要具有相同长度的数组   每个级别。

答案 1 :(得分:1)

String[][] a = new String[3][];

相当于:

String[] a1 = null;
String[] a2 = null;
String[] a3 = null;
String[][] a = {a1, a2, a3};

a[0][0]类似于引发NPE的a1[0]


这里有两个选项:

  • 将数组定义为:
String[][] a = new String[3][3];
  • 或在a
  • 中创建新数组
a[0] = new String[2];
a[1] = new String[4];
a[2] = new String[3];

请注意,使用后一种方法,您可以为内部数组设置不同的大小。

答案 2 :(得分:1)

良好的发现。使用这两个参数初始化2D数组时,会发生以下情况:

String[][] a = new String[5][5]

2D Array with both bounds

但是当你指定第二个界限时,会发生什么:

String[][] a = new String[5][];

2D Array with no inner bound

在第4行中,您会得到确切的NullPointerException,因为:

String[][] a = new String[10][];
System.out.println(a[0][0]); // << a[0] is null!

但为什么你甚至需要这种行为?它很简单。它适用于二维数组中的每个元素可以具有不同数量的元素的情况。潜在的用例场景是:

enter image description here

这种行为有很好的使用案例,例如优先级队列(每个优先级可以在队列中有不同数量的项目),哈希表(它的溢出部分)等。