2

当我尝试访问我创建的数组的元素并且不知道为什么时,我不断收到 NullPointerException。抛出的代码:

    TreeNode[] list1;
    list1 = new TreeNode[1000];
    list1[0].edges = new EdgeNode(1); //Throw line

但如果我这样做,它会起作用:

    TreeNode[] list1;
    list1 = new TreeNode[1000];
    list1[0] = new TreeNode();
    list1[0].edges = new EdgeNode(1);

我不知道为什么。显然,我可以 for 循环遍历整个数组并创建新元素,但这不会破坏 new 的意义吗?此外,如果相关,我已经为 TreeNode 定义了默认构造函数。

4

7 回答 7

2

你实际上回答了你自己的问题:数组的元素应该单独初始化。默认情况下,它们用于对象null数组。因此。NullPointerException

于 2013-11-11T01:39:48.150 回答
2

这正是java的工作原理。创建数组时,所有元素都初始化为null,您需要对其进行初始化。那是因为它无法确定您是否只想使用默认构造函数构造它们,或者使用具有常量参数的不同构造函数,或者具有不同参数的不同构造函数,或者 null,或者什么。所以它只是将数组初始化为null.

于 2013-11-11T01:40:32.713 回答
1

你说之后list1 = new TreeNode[1000]

list1 是一个充满空值的新数组。

所以你必须循环并初始化它

它并没有破坏 new 的意义,因为当你说 new A[10000] 时,那是分配一个新数组,而不是它的元素。说list1[0] = new TreeNode();分配一个元素。

我同意这并不优雅,但那是你的 java。:)

于 2013-11-11T01:42:56.253 回答
0

当您调用时,new TreeNode[1000]您正在实例化一个引用数组,而不是对象本身。这是正常的,因为编译器不能只假设要调用哪个构造函数。想象一下,如果您有一个没有无参数构造函数的类:您认为在这种情况下编译器将如何实例化它?

于 2013-11-11T01:41:00.137 回答
0

此场景涉及两个初始化

  1. 数组的初始化
  2. 数组元素的初始化

    new TreeNode[1000] 只初始化数组而不是数组元素。

于 2013-11-11T01:41:22.043 回答
0
list1 = new TreeNode[1000];

这只是创建一个new TreeNode数组。数组本身就是一个对象。所以不要让new关键字欺骗你。因此,使用上面的代码,您所拥有的只是一个类型数组TreeNode。那只保存一个TreeNode类型的值。不给它任何 TreetNode` 值。你必须自己用代码明确地做到这一点。

于 2013-11-11T01:43:57.523 回答
0

当您创建新的对象数组时,默认情况下会填充nulls 所以当您执行时

list1[0].edges

实际上,您正在尝试执行

null.edges

这是不正确的,因为null没有edges.

数组在创建后没有被新对象填充的原因很少:

  1. 在许多(如果不是大多数)情况下,我们希望将已经存在的数组对象放入数组中,因此创建新的对象会浪费时间。
  2. 编译器应该使用哪个构造函数来创建填充数组的对象?
  3. 在这样的构造函数中应该使用什么参数?
  4. 请记住,数组可以是无法实例化的类数组,例如抽象类或接口。编译器将如何填充这样的数组?应该使用哪个子类?
于 2013-11-11T02:02:04.873 回答