简体   繁体   English

为什么我不能访问类数组索引

[英]why can i not access a class array index

I keep getting a NullPointerException when I try to access elements of an array I created and don't know why. 当我尝试访问我创建的数组的元素并且不知道为什么时,我一直收到NullPointerException。 The code that throws: 抛出的代码:

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

but if I do this, it works: 但是如果我这样做,它会起作用:

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

and I don't know why. 我不知道为什么。 Obviously I could for loop through the whole array and make new elements but doesn't that defeat the point of new? 显然,我可以遍历整个数组并创建新元素,但这不会破坏新观点吗? Also, if relevant, I have defined the default constructor for TreeNode. 另外,如果相关的话,我已经定义了TreeNode的默认构造函数。

You actually answered your own question: elements of an array should be individually initialized. 您实际上回答了自己的问题:数组的元素应单独初始化。 By default they are null for array of objects . 默认情况下,对于对象数组,它们为null Hence NullPointerException . 因此, NullPointerException

This is exactly how java works. 这正是java的工作方式。 When you create an array, all elements are initialized to null , and you need to initialize them. 创建数组时,所有元素都初始化为null ,并且需要初始化它们。 That is because there is no way it could find out whether you just wanted them constructed with the default constructor, or with a different constructor with constant parameters, or a different constructor with varying parameters, or null, or what. 这是因为无法找到您是要使用默认构造函数还是使用具有恒定参数的其他构造函数,还是使用具有可变参数的其他构造函数(或者为null)构造它们。 So it just initializes the array to null . 因此,它只是将数组初始化为null

After you say list1 = new TreeNode[1000] , 在您说list1 = new TreeNode[1000]

list1 is a new array full of nulls. list1是一个包含空值的新数组。

So you have to loop through and initialise it 所以你必须遍历并初始化它

It does not defeat the point of new, because when you say new A[10000], that is allocating a new array, not its' elements. 它不会击败new的观点,因为当您说new A [10000]时,它分配的是新数组,而不是其元素。 Saying list1[0] = new TreeNode(); list1[0] = new TreeNode(); allocates an element. 分配一个元素。

I agree this isn't elegant but that is java for you. 我同意这不是很优雅,但是适合您。 :) :)

When you call new TreeNode[1000] you are instantiating an array of references, not the objects themselves. 当您调用new TreeNode[1000]您将实例化一个引用数组,而不是对象本身。 This is normal since the compiler can't just assume which constructor to call. 这是正常现象,因为编译器不能仅假设要调用哪个构造函数。 Imagine if you had a class that didn't have a no-argument constructor: how do you think the compiler would have to instantiate it in that case? 想象一下,如果您有一个没有无参数构造函数的类:在这种情况下,您如何认为编译器必须实例化它?

There are two Initialization involved in this scenario 在这种情况下涉及两个初始化

  1. Initialization of the Array 数组初始化
  2. Initialization of Array Elements 数组元素的初始化

    new TreeNode[1000] only initializes Array not Array Elements. new TreeNode [1000]仅初始化数组,而不初始化数组元素。

list1 = new TreeNode[1000];

This is only creating a new TreeNode array. 这只是创建一个new TreeNode数组。 The array itself is an object. 数组本身是一个对象。 So don't let the new keyword fool you. 因此,请勿让new关键字欺骗您。 So with the above code, all you have is an array of TreeNode type. 因此,使用上面的代码,您所拥有的只是一个TreeNode类型的数组。 That only holds values of a TreeNode type. 那只保存TreeNode类型的值。 Does not give it any TreetNode` value. 不给它任何TreetNode的值。 You must do that explicity yourself with code. 您必须使用代码来明确地做到这一点。

When you create new array of objects it is by default filled with null s so when you are executing 创建新的对象数组时,默认情况下会用null填充,因此在执行时

list1[0].edges

in reality you are trying to execute 实际上,您正在尝试执行

null.edges

which is incorrect since null doesn't have edges . 这是不正确的,因为null没有edges

There are few reasons why arrays are not filled with new objects after being created: 创建数组后,没有用新对象填充数组的原因很少:

  1. In many (if not most) cases we want to place in array objects that already exists, so creating new ones would be waste of time. 在很多(如果不是大多数)情况下,我们希望放置在已经存在的数组对象中,因此创建新对象将浪费时间。
  2. Which constructor should compiler use to create objects that would fill array? 编译器应使用哪个构造函数来创建将填充数组的对象?
  3. What arguments should be used in such constructor? 在此类构造函数中应使用哪些参数?
  4. Remember that array can be array of classes that can't be instantiated like abstract classes or interfaces. 请记住,数组可以是无法实例化的类的数组,例如抽象类或接口。 How would compiler fill such array? 编译器将如何填充此类数组? Which subclass should be used? 应该使用哪个子类?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM