Java程序中结构的null指针异常



我正在用Java编写一个程序,从文件中读取一些内容,并将所有内容存储在数组中。阵列中的每个插槽都是一个链表。我得到一个空指针异常,我不知道为什么。我对编程很陌生,我有一种可怕的感觉,这是我看不到的显而易见的东西,但每个看过它的人都会花上两秒钟的时间来弄清楚。。。然后我会觉得自己很愚蠢,但无论如何,这是。。。

根据我的调试器(我使用的是Eclipse),NPE在GiveJob类中。我已经用所有的大写字母标记了这条线,以便于找到它

我对NPE的第一个想法是,它一定与我有一个结构数组这一事实有关。据我所知,在使用Java时,对象数组中的每个槽都会自动初始化为null,我认为这将包括一个structs数组。我错了吗?

非常感谢任何帮助,因为我已经为此困惑了很长一段时间:-p

这是数组的类:

public class Person{
String name;
Jobs jobs;
}

这是链接列表的类:

public class Jobs{
String typeOfJob;
Jobs next;
}

这是给人一份工作的课程:

public void GiveJob(String personName, String newJob int N, Person[] people){
    //go through the array of people to see if the person already exists
    for(int i=0; i<N; i++){
        //check to see if the person has already been added
        if(people[i].jobs != null){                 //NULL POINTER EXCEPTION
            if(people[i].jobs.compareToIgnoreCase(newJob) == 0){
                //if the person has been added, check to see if the job has
                //already been added
                Jobs currentNode = people[i].jobs;
                while(currentNode.next != null){
                    //if the job has already been added, break
                    if(currentNode.typeOfJob.compareToIgnoreCase(newJob) == 0){
                        break;
                    }
                    currentNode = currentNode.next;
                }
                //if the job has already been added, break
                if(currentNode.typeOfJob.compareToIgnoreCase(newJob) == 0){
                    break;
                }
                else{
                    Jobs tempNode = new Jobs();
                    tempNode.typeOfJob = newJob;
                    tempNode.next = null;
                    people[i].jobs.next = tempNode;
                }               
            }//end if the job has already been added
        }
        //if the person has not been added yet, add him/her
        else if(people[i] == null){
            people[i].name = personName;
            Jobs tempNode = new Jobs();
            tempNode.typeOfJob = newJob;
            tempNode.next = null;
            people[i].jobs = tempNode;
            break;
        }
    }//end for(int i=0; i<N; i++) - checking if the city has been added already
}//end addToAdjList method
}//end AdjacencyList class

这是包含main的类:

import java.io.*;
import java.util.*;
public class LookingForAJob {
public static void main(String[] args) {
    //read in file
    try{
        File filename = new File("jobListing.txt");
        Scanner fin = new Scanner(filename);
        //read in the number of people (N) from file
        int N = fin.nextInt();
        //read in the number of jobs available (M) from file
        int M = fin.nextInt();
        //create a new instance of GiveJob
        GiveJob jobSearch = new GiveJob();
        //Create the array to put the people into
        Person people[] = new Person[N];
        //read in information from file
        for(int i=0; i<M; i++){
            //get person's name
            String personName = fin.next();             
            //get job name
            String jobName = fin.next();
            //put what was read in from the file into an linked list
            jobSearch.GiveJob(personName, jobName, N, people);
        }//end for(int i=0; i<M; i++)
    }//end try
    catch(FileNotFoundException e){
        System.err.println("Input file not found for reading!");
        System.exit(0);
    }
    catch(Exception e){
        System.err.println("Input file not in correct format");
        System.exit(0);
    }
}

}

您的代码似乎有很多错误-不幸的是,您试图减少问题中发布的代码数量(这通常是一件好事)也适得其反,因为这使得您更难确定代码中的错误以及复制粘贴的东西时的错误。

在我开始向您解释一些东西之前,请注意,您可能需要查看一些网站或其他地方,这些网站或地方有助于从C语言过渡到Java,因为您在一些基本问题上出错了。这并不是你的编程能力的问题,你只是不知道Java与C的区别,比如如何做条件语句。

无论如何,我认为问题是,你的类中的值,事实上,类本身还没有初始化/实例化(你已经命名了它们,因为你现在可以为它们设置值等等,但它们实际上还没有任何值)。让我们先处理一些小问题,您需要实例化类中的值,如Jobs和Person。实现这一点的方法是通过构造函数(如果你不确定我所说的内容,请看一看Java编程网站或书籍的介绍)。在确保name之类的值不为null之后,您将不得不在某个地方实例化Person类。您似乎希望在GiveJob方法中执行此操作(该方法以不合适的样式命名,并且缺少其中一个参数的类型声明)。因此,您必须实例化Person对象(类似于people[i] = new Person(/*args*/))。

您要求解决的特定问题在于,您的Person数组中还没有实例化的Person。但是,您正试图(再次以不适当的方式)访问该Person的变量。此人不存在,属于null类型。null没有属于它的jobs变量。因此,您会得到一个空指针错误。

@棘轮怪胎和@SQiShER有办法修复它,并适当地显示。然而,您仍然需要查看基本的Java编码指南,以帮助您适应新的情况和适当的风格方法。

Person people[] = new Person[N];

这只是创建了一个大小为N的数组,其中填充了NULL。我没有看到任何初始化代码然后在GiveJob函数中调用people[i].job。像这样的

for(int i=0; i<N ;i++ ){
   people[i] = new Person();
}
  for(int i=0; i<N; i++){
        //check to see if the person has already been added
        if(people[i].jobs != null){                 //NULL POINTER EXCEPTION

相反,你应该像这样遍历你的数组:

      for(int i=0; i<people.length; i++){
                  if(people[i].jobs != null){    
}

在那一行中,逗号也不见了:

public void GiveJob(String personName, String newJob int N, Person[] people)

字符串之后,int 之前

交换if around:首先检查人员是否已添加,然后检查其工作:

for(int i=0; i<people.length; i++){
    //if the person has not been added yet, add him/her
    if(people[i] == null){
        people[i] = new Person();
        people[i].name = personName;
        Jobs tempNode = new Jobs();
        tempNode.typeOfJob = newJob;
        tempNode.next = null;
        people[i].jobs = tempNode;
        break;
    }        
    //check to see if the person has already been added
    if(people[i].jobs != null){                 //NULL POINTER EXCEPTION
        if(people[i].jobs.compareToIgnoreCase(newJob) == 0){
            //if the person has been added, check to see if the job has
            //already been added
            Jobs currentNode = people[i].jobs;
            while(currentNode.next != null){
                //if the job has already been added, break
                if(currentNode.typeOfJob.compareToIgnoreCase(newJob) == 0){
                    break;
                }
                currentNode = currentNode.next;
            }
            //if the job has already been added, break
            if(currentNode.typeOfJob.compareToIgnoreCase(newJob) == 0){
                break;
            }
            else{
                Jobs tempNode = new Jobs();
                tempNode.typeOfJob = newJob;
                tempNode.next = null;
                people[i].jobs.next = tempNode;
            }               
        }//end if the job has already been added
    }
}

一个简单的解决方案是更改if条件的顺序,以便首先检查数组元素是否为null,如果为null,则通过分配一个新的Person实例来初始化它,如下所示:people[i] = new Person()

固定代码:

   if(people[i] == null){
        people[i] = new Person(); // ADD THIS LINE TO FIX THE NPE
        people[i].name = personName;
        Jobs tempNode = new Jobs();
        tempNode.typeOfJob = newJob;
        tempNode.next = null;
        people[i].jobs = tempNode;
        break;
    } else if(people[i].jobs != null){
        if(people[i].jobs.compareToIgnoreCase(newJob) == 0){
            //if the person has been added, check to see if the job has
            //already been added
            Jobs currentNode = people[i].jobs;
            while(currentNode.next != null){
                //if the job has already been added, break
                if(currentNode.typeOfJob.compareToIgnoreCase(newJob) == 0){
                    break;
                }
                currentNode = currentNode.next;
            }
            //if the job has already been added, break
            if(currentNode.typeOfJob.compareToIgnoreCase(newJob) == 0){
                break;
            }
            else{
                Jobs tempNode = new Jobs();
                tempNode.typeOfJob = newJob;
                tempNode.next = null;
                people[i].jobs.next = tempNode;
            }               
        }//end if the job has already been added
    }

您需要这样做,因为您使用Person people[] = new Person[N];创建的Array的元素仍然为null,因此您尝试访问的属性的内存尚未分配。Java没有任何类似于C结构的东西,所以结构只是一个简单的Java对象,在访问其字段之前,它需要用new进行实例化。

相关内容

  • 没有找到相关文章

最新更新