Java 空指针异常,“尝试从空对象引用上的字段读取”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32287095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Null pointer exception, "Attempt to read from field on a null object reference"
提问by Lucas B
I am making an app in which the user types in a list of tasks, and that list is saved to an array. Each task in the array is an instance of the Assignment
class. However, I realized that in java it is not possible to add an element to an array after the array is created. So, what I did was I created an array called tasks
which consisted of many null values: Assignment[]tasks = {null, null, null, null, null, null, null, null, null, null, null, null};
. When I want to add a task to the array, I just replace the next null value with the object. However, I also need to have an array of just the tasks, with no null values. So I created an array called full_tasks
for all of the elements that aren't null:
我正在制作一个应用程序,用户在其中键入任务列表,并将该列表保存到数组中。数组中的每个任务都是Assignment
类的一个实例。但是,我意识到在 java 中无法在创建数组后向数组添加元素。所以,我所做的是创建了一个名为的数组tasks
,它由许多空值组成:Assignment[]tasks = {null, null, null, null, null, null, null, null, null, null, null, null};
. 当我想向数组中添加一个任务时,我只是用对象替换下一个空值。但是,我还需要一个只有任务的数组,没有空值。所以我创建了一个数组,调用full_tasks
所有不为空的元素:
for (Assignment task: tasks) {
if (task != null) {
realLength += 1;
}
}
Assignment[] full_tasks = new Assignment[realLength];
for (int i=0; i <= full_tasks.length - 1; i++) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
So now, the full_tasks
array should be an array of all the tasks, none of which are null, right? However, when I run the app, it can't launch the activity, an error it says is caused by a null pointer exception:
所以现在,full_tasks
数组应该是所有任务的数组,没有一个是空的,对吧?但是,当我运行应用程序时,它无法启动活动,它说的错误是由空指针异常引起的:
Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.example.lb.homeworkappv11.Assignment.name' on a null object reference
at com.example.lb.homeworkappv11.Schedule.sortTasks(Schedule.java:64)
The line that the error points to is:
错误指向的行是:
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
I'm still not totally sure what a null object reference is, but I think it means that one of the elements in the full_tasks
array is null. Would that be correct? And if it is, what can I do to make sure that the full_tasks
array is onlythe non-null elements in the tasks
array?
我仍然不完全确定空对象引用是什么,但我认为这意味着full_tasks
数组中的元素之一为空。那会是正确的吗?如果是,我该怎么做才能确保full_tasks
数组只是数组中的非空元素tasks
?
Thank you so much!
非常感谢!
Edit:the constructor function for the assignment class is:
编辑:赋值类的构造函数是:
public Assignment(String name, int days, int time) {
this.name = name;
this.days_due = days;
this.time = time;
this.toSortBy = "nothing";
}
采纳答案by Sascha Kolberg
A null
reference is just that null
. In your code it is tasks[i].name
where you try to call name
on tasks[i]
so tasks[i]
is null
.
一个null
参考就是这样null
。在你的代码是tasks[i].name
在您尝试调用name
上tasks[i]
这样tasks[i]
的null
。
There is one scenario I can think of, where your code would definitely throw a NullPointerException
.
So, I will assume your tasks array can look looks like this:
我能想到的一种情况是,您的代码肯定会抛出NullPointerException
. 所以,我假设你的任务数组看起来像这样:
tasks = [task0, null, task2, task3, null, task5]
Then full_tasks
will have a size of 4 but
然后full_tasks
将有一个大小为 4 但
for (int i=0; i <= full_tasks.length - 1; i++) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
will throw a NPEas soon as i == 1
because tasks[1]
is null
.
会尽快抛出NPEi == 1
因为tasks[1]
是null
。
So, if you want to fill full_tasks
with only non-null tasks make sure you got the right indexes of tasks
.
因此,如果您只想填充full_tasks
非空任务,请确保您获得了正确的tasks
.
回答by Rehman
Seems like "tasks" list is empty. Make sure its get populated or put a null check like :
似乎“任务”列表是空的。确保它被填充或放置一个空检查,如:
if(tasks[i] !=null) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
回答by Derek Fung
You can think of null as something not exists, for example when you try to get task.name
, where task is null, you get error, because you try to get name from some something which does not even exists.
您可以将 null 视为不存在的东西,例如,当您尝试 get 时task.name
, task 为null,您会收到错误,因为您尝试从一些甚至不存在的东西中获取名称。
Actually what your code is doing now is check how many non-null items in the original array, and try to extract the extra the first n items from the array to a new array.
实际上你的代码现在正在做的是检查原始数组中有多少非空项,并尝试从数组中提取额外的前 n 项到一个新数组。
i.e. if the list is {null, null, non-null, non-null}
, it has 2 non-null item, however your code wrongly extracts the list of the first 2 items which are {null, null}
即,如果列表是{null, null, non-null, non-null}
,则它有 2 个非空项目,但是您的代码错误地提取了前 2 个项目的列表{null, null}
Edit, to actually do what you want:
编辑,实际做你想做的事:
ArrayList<Assignment> fullTaskList = new ArrayList<Assignment>();
for (Assignment task: tasks) {
if (task != null) {
fullTaskList.add(task);
}
}
//optional
Assignment[] fullTasks = fullTaskList.toArray(new Assignment[fullTaskList.size()]);
回答by George
The problem in your code is here:
您的代码中的问题在这里:
(tasks[i].name, tasks[i].days_due, tasks[i].time).
Although you're counting the real size, there could be some null value in between that is causing it to be get a null object from the list tasks[i].
尽管您正在计算实际大小,但两者之间可能存在一些空值导致它从列表任务 [i] 中获取空对象。
A good idea to solve this is by using a List instead of an Array. A List can be increased or decreased as you want, you just have to add or remove an item of your object type. For example:
解决这个问题的一个好主意是使用列表而不是数组。可以根据需要增加或减少列表,您只需添加或删除对象类型的项目。例如:
List<Assignment> list = new ArrayList<>();
Assignment assignment1 = new Assignment(etc.);
list.add(assignment1);
list.get(0) //-> returns the Assignment object that you added.
Then you can use list.size()
to get the size to know how many items are there, or to remove the last item. And you would have no problems to add new items to the list.
然后您可以使用list.size()
来获取大小以了解有多少项目,或者删除最后一个项目。而且您将新项目添加到列表中没有问题。
回答by Wololo
Here's what I think
这是我的想法
You are just finding the number elements that are not null
. You don't know where in the array thest null
's are present.
您只是在查找不是 的数字元素null
。你不知道数组中的哪个地方null
存在thest 。
Suppose ONLY the first element is null
. So realLength
will be 7. The latter for
loop runs from i=0
to i=7
. When i=0
, tasks[i].name
tries to access the name
field of the first element; but your first element happens to be null`. That's where things go wrong.
假设只有第一个元素是null
。因此,realLength
将7后者for
从循环运行i=0
到i=7
。当i=0
,tasks[i].name
尝试访问name
第一个元素的字段;但你的第一个元素恰好是 null`。这就是事情出错的地方。
Solution:
解决方案:
There are a number of solutions. The most efficient one I can think of uses an ArrayList
.
有多种解决方案。我能想到的最有效的方法是使用ArrayList
.
To get around using arrays, you should store the indices of all elements that are not null
. That's one way.
为了避免使用数组,您应该存储所有不是 的元素的索引null
。那是一种方式。
Here's another:
这是另一个:
for (Assignment task: tasks) {
if (task != null) {
realLength += 1;
}
}
Assignment[] full_tasks = new Assignment[realLength];
int count = 0;
for (Assignment task: tasks) {
if (task != null) {
full_tasks[count] = new Assignment(task.name, tasks.days_due, task.time);
count++;
}
}
回答by Floern
It seems you are trying to copy and compact the tasks
array into the full_tasks
array (removing the null elements), but you are doing this partially incorrect since you are accessing tasks[i]
in the second loop without checking whether its is null.
似乎您正在尝试将tasks
数组复制并压缩到full_tasks
数组中(删除空元素),但是您这样做部分不正确,因为您tasks[i]
在第二个循环中访问而不检查其是否为空。
Instead of:
代替:
for (int i=0; i <= full_tasks.length - 1; i++) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
you could write something like this:
你可以这样写:
for (int i = 0, f = 0; i < tasks.length; i++) {
if (tasks[i] != null) {
full_tasks[f] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
f++;
}
}
But then again to solve your original problem, regarding the fact that you cannot add any elements to an array, I suggest to use an ArrayList
instead of a simple array. This allows you to add items with ArrayList.add(assignment)
and remove them again with ArrayList.remove(index)
.
但是再次解决您的原始问题,关于您无法向数组添加任何元素的事实,我建议使用 anArrayList
而不是简单的数组。这允许您使用 来添加ArrayList.add(assignment)
和删除项目ArrayList.remove(index)
。