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
的数字元素。您不知道st
null
在数组中的位置

假设只有第一个元素是
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++;
    }
}