我正在用Java编写一个程序,它从文件中读取一些内容并将所有内容存储在一个数组中。数组中的每个插槽都是一个链表。我得到一个空指针异常,我不知道为什么。我对编程非常陌生,而且我有一种可怕的感觉,这是我看不到的明显的东西,但每个人都会看到它,哦,我不知道,也许两秒钟才能弄明白。 ..然后我会感到愚蠢,但无论如何,这里...... ...
根据我的调试器(我正在使用Eclipse),NPE位于GiveJob类中。我已经用全部大写标记了这一行,以便于找到它。
我对NPE的第一个想法是它必须与我有一系列结构的事实有关。据我所知,使用Java时,对象数组中的每个插槽都会自动初始化为null,我认为这将包含一个结构数组。我错了吗?
非常感谢任何帮助,因为我一直在为此困惑一段时间:-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);
}
}
}
答案 0 :(得分:4)
您的代码似乎存在许多问题 - 遗憾的是,您尝试减少问题中发布的代码量(这通常是一件好事)也是因为它更难以确定什么是代码中的错误以及复制粘贴内容时的错误。
在我开始向您解释一些内容之前,您可能想要查看一些网站或其他有助于从C语言转换到Java的地方,因为您会遇到一些基本的错误。这并没有对你的编程能力造成任何影响,你只是不知道将Java与C区别开来的一些东西,例如如何进行条件化。
无论如何,我认为问题在于你的类中的值,实际上类本身还没有被初始化/实例化(你已经命名了它们,因为你现在能够为它们设置值,所以在,但他们实际上没有任何价值观)。让我们首先处理小事,你需要在你的类中实例化像Jobs和Person这样的值。这样做的方法是通过构造函数(如果你不确定我正在谈论的事情,请看一下Java编程网站的介绍或预订)。在确保name
之类的值不为空之后,您将不得不在某处实例化Person
类。您似乎希望在GiveJob
方法中执行此操作(以不合适的样式命名,并且缺少其中一个参数的类型声明)。因此,您将不得不实例化Person对象(people[i] = new Person(/*args*/)
行)。
您要求解决的特殊问题在于您的人员数组中还没有实例化的Person。但是,您尝试从该Person访问(再次以不恰当的方式)变量。此人不存在,属于null
类型。 null
没有属于它的jobs
变量。因此,您将获得空指针错误。
@ratchet freak和@SQiShER有办法解决它显示的问题。但是,您仍然希望查看基本的Java编码指南,以帮助您适应新情况和适当的风格方法。
答案 1 :(得分:1)
Person people[] = new Person[N];
这只会创建一个大小为N且充满NULL
的数组。我没有看到任何初始化代码
在people[i].job
函数中调用GiveJob
之前。像这样的东西,
for(int i=0; i<N ;i++ ){
people[i] = new Person();
}
答案 2 :(得分:0)
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)
在String之后,在int之前
答案 3 :(得分:0)
一个简单的解决方案是更改if条件的顺序,以便首先检查数组元素是否为null,如果是,则通过分配新的Person
实例来初始化它,如下所示:{{1} }
固定代码:
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
}
创建的Array的元素仍为null,因此尚未分配您尝试访问的属性的内存。 Java与C结构没有任何相似之处,所以 struct 只是一个简单的Java对象,需要先用new实例化,才能访问它的字段。
答案 4 :(得分:0)
交换if周围:首先检查是否已添加此人,然后检查它的工作:
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
}
}