Java 空指针异常,";尝试从空对象引用上的字段读取;
我正在制作一个应用程序,用户在其中键入任务列表,并将该列表保存到一个数组中。数组中的每个任务都是Java 空指针异常,";尝试从空对象引用上的字段读取;,java,android,arrays,nullpointerexception,Java,Android,Arrays,Nullpointerexception,我正在制作一个应用程序,用户在其中键入任务列表,并将该列表保存到一个数组中。数组中的每个任务都是赋值类的一个实例。但是,我意识到,在java中,在创建数组之后,不可能将元素添加到数组中。因此,我所做的是创建了一个名为tasks的数组,它由许多空值组成:Assignment[]tasks={null,null,null,null,null,null,null}。当我想向数组中添加任务时,我只是用对象替换下一个空值。但是,我还需要一个只包含任务的数组,没有空值。因此,我为所有非空元素创建了一个名为f
赋值
类的一个实例。但是,我意识到,在java中,在创建数组之后,不可能将元素添加到数组中。因此,我所做的是创建了一个名为tasks
的数组,它由许多空值组成:Assignment[]tasks={null,null,null,null,null,null,null}代码>。当我想向数组中添加任务时,我只是用对象替换下一个空值。但是,我还需要一个只包含任务的数组,没有空值。因此,我为所有非空元素创建了一个名为full\u 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);
}
错误指向的行是:
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
我仍然不能完全确定空对象引用是什么,但我认为这意味着full\u tasks
数组中的一个元素是空的。是这样吗?如果是,我可以做什么来确保full_tasks
数组仅任务数组中的非空元素
非常感谢你
编辑:赋值类的构造函数是:
public Assignment(String name, int days, int time) {
this.name = name;
this.days_due = days;
this.time = time;
this.toSortBy = "nothing";
}
似乎“任务”列表是空的。确保其已填充或进行空检查
比如:
您可以将null视为不存在的东西,例如,当您尝试获取任务.name
,其中任务为null,您会得到错误,因为您尝试从一些甚至不存在的东西获取名称
实际上,您的代码现在要做的是检查原始数组中有多少个非null项,并尝试将前n个项中的多余项从数组提取到新数组中
i、 e.如果列表为{null,null,non null,non null}
,则它有两个非null项,但是您的代码错误地提取了前两个项的列表,它们是{null,null}
编辑,以实际执行所需操作:
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()]);
ArrayList fullTaskList=新建ArrayList();
对于(分配任务:任务){
如果(任务!=null){
完整任务列表。添加(任务);
}
}
//可选的
分配[]fullTasks=fullTaskList.toArray(新分配[fullTaskList.size()]);
代码中的问题如下:
(tasks[i].name, tasks[i].days_due, tasks[i].time).
虽然您正在计算实际大小,但在这两者之间可能存在一些空值,这导致它从列表任务[i]中获取空对象
解决这个问题的一个好办法是使用列表而不是数组。列表可以根据需要增减,只需添加或删除对象类型的项即可。例如:
List<Assignment> list = new ArrayList<>();
Assignment assignment1 = new Assignment(etc.);
list.add(assignment1);
list.get(0) //-> returns the Assignment object that you added.
List List=new ArrayList();
转让转让1=新转让(等);
列表。添加(转让1);
list.get(0)/->返回您添加的赋值对象。
然后,您可以使用list.size()
获取大小以了解有多少项,或者删除最后一项。您将不会有任何问题向列表中添加新项目。一个null
引用就是null
。在代码中,它是tasks[i].name
在tasks[i]
上尝试调用name
的地方,因此tasks[i]
是null
我可以想到一个场景,您的代码肯定会抛出NullPointerException
。
因此,我假设您的任务数组可以如下所示:
tasks = [task0, null, task2, task3, null, task5]
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++;
}
}
然后,完整任务的大小将为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);
}
for(inti=0;i以下是我的想法
您只是在查找非null
的数字元素。您不知道stnull
在数组中的位置
假设只有第一个元素是null
。因此realLength
将是7。
的后一个循环从i=0
运行到i=7
。当i=0
时,tasks[i].name
尝试访问第一个元素的name
字段;但您的第一个元素恰好为null`。这就是问题所在
解决方案:
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()]);
有很多解决方案。我能想到的最有效的解决方案是使用ArrayList
为了避免使用数组,您应该存储所有非null
元素的索引。这是一种方法
还有一个:
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++;
}
}
您似乎试图将任务
数组复制并压缩到完整任务
数组中(删除空元素),但这样做部分是错误的,因为您在第二个循环中访问任务[i]
,而没有检查其是否为空
而不是:
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);
}
for(int i=0;i)你在赋值中的“name”变量为null。你能发布你正在使用的构造函数的代码吗?我在上面添加了代码非常感谢!这个答案非常有用。我修改了for循环,使它只接受非null元素,现在它可以工作了!
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++;
}
}