2012-03-20 62 views
0

我对Java很新,我遇到了一个我自己无法解决的问题。我搜索了例外情况,但只要我能理解,问题就太具体了,所以我在这里找到了自己。这是我的问题。从Java文件和空指针中读取异常

我有一类称为学生具有休耕数据成员和他们的get/set方法:

private String studentNumber; 
private String firstName; 
private String lastName; 
private int age; 
private String gender; 
private String country; 

和我创建的实例数组作为休耕:

Student studentList[] = new Student(10); 

我有一个数据库(一个文本文件)作为休耕

081935 Cengiz rrrrr Male 21 Turkey 
082935 Ayşe aaaaa Female 22 England 
083935 Onur bbbbb Male 23 Germany 
084935 Fatma ccccc Female 24 Cyprus 
085935 Ali dddd Male 21 China 
086935 Zehra eeee Female 22 Denmark 
087935 Murat ffff Male 25 France 
088935 Selin ggggg Female 26 Japan 
086935 Cengiz hhhh Male 20 Korea 
080935 Damla qqqqqq Female 19 Iran 

我想要做的是获取所有这些informati附件我的类的实例,我尝试实现这一目标是休耕:

import java.io.*; 
import java.util.Scanner; 

public class StudentTracker { 

    private static int counter = 0; 
    private static Student studentList[]; 

    public static void readFromFile() throws FileNotFoundException { 
     File file = new File("Database.txt"); 
     Scanner scanner = new Scanner(new FileReader(file)); 
     try { 
       while (scanner.hasNextLine()){ 
       processLine(scanner.nextLine()); 
       } 
     } finally { 
      scanner.close(); 
     } 
    } 


    public static void processLine(String line) { 
     Scanner scanner = new Scanner(line); 
     scanner.useDelimiter(" "); 
     if (scanner.hasNext()) { 
      studentList[counter].setStudentNumber(scanner.next()); 
      studentList[counter].setFirstName(scanner.next()); 
      studentList[counter].setLastName(scanner.next()); 
      studentList[counter].setGender(scanner.next()); 
      studentList[counter].setAge(Integer.parseInt(scanner.next())); 
      studentList[counter].setCountry(scanner.next());  
      counter++; 
     } 
     else { 
      System.out.println("Empty or invalid line. Unable to process."); 
     } 
     } 

    public static void main(String[] args) throws FileNotFoundException { 

     studentList = new Student[10]; 
     readFromFile(); 
     for(int i = 0; i < 10; i++) { 
      System.out.printf(studentList[i].getStudentNumber(), " ", 
           studentList[i].getFirstName()); 

     } 

    } 

} 

,但它给休耕错误:

Exception in thread "main" java.lang.NullPointerException 
    at StudentTracker.processLine(StudentTracker.java:28) 
    at StudentTracker.readFromFile(StudentTracker.java:16) 
    at StudentTracker.main(StudentTracker.java:68) 

的方式找不到像C-的scanf它得到了一个功能输入,直到第一个空格,所以我找到另一种方法来解析字符串从

readFromFile()和processLine函数,但我不确定他们是否按预期工作。

先谢谢您

+0

scanner.nextLine() – 2012-03-20 17:26:33

回答

5

这条线:

studentList = new Student[10]; 

创建10个元素的数组。每个元素的值不是Student对象;它是一个参考 - 并且该引用将为空或对Student对象(或兼容类型)的引用。每个元素都有一个空值来开始。

该行不会创建任何Student对象

在设置属性之前,您需要创建一个Student的实例,例如,

if (scanner.hasNext()) { 
    studentList[counter] = new Student(); 
    studentList[counter].setStudentNumber(scanner.next()); 
    ... 

或者:

if (scanner.hasNext()) { 
    Student student = new Student(); 
    student.setStudentNumber(scanner.next()); 
    ... fill in the other properties ... 
    studentList[counter] = student; 
    ... 

作为一个侧面说明,这条线:

private static Student studentList[]; 

...不是一个地道的声明。这是有效的,但大多数Java程序员宁愿看到:

private static Student[] studentList; 

这样所有的类型信息都保存在一个地方。 (我也建议使用List<Student>来代替,并将它传入方法而不是使用静态变量,但是让我们不要超越自己...)

+0

+1,良好的信息附: - ) – 2012-03-20 17:32:55

1

您创建了一个Student数组,但从未放入任何Student对象。

不是将它们设置为数组索引值,而是将它们设置为数组索引值,创建一个新对象,设置其属性,然后将其分配给数组索引。

for(...) { 
Student x= new Student(); 
x.set... 
studentList[index]= x; 
} 
0
在ProcessLine从

你引用studentList [计数器],但你从来没有把新的学生到studentList [计数器]所以你尝试调用setStudentName上的空。你应该把一个新的学生到studentList在种台,然后用它,或者使其更具可读性,这样做

Student = new Student(); 
student.setThis(scanner.next()); 
student.setThat(scanner.next()); 
studentList[counter] = student; 
0

您应该粘贴28行正在获得例外。有几件事要检查:

  1. studentList[counter]非null?

  2. 确认scanner.hasNext()true后,您几次拨打scanner.next()。其中一个电话可以返回null?这不是这里的根本原因,因为异常在堆栈上至少有一个以上的方法,但您仍然可能需要在代码中进行检查。

2

除了未初始化的元素在studentList,这里也

if (scanner.hasNext()) { 
     studentList[counter].setStudentNumber(scanner.next()); 
     studentList[counter].setFirstName(scanner.next()); 
     studentList[counter].setLastName(scanner.next()); 
     studentList[counter].setGender(scanner.next()); 
     studentList[counter].setAge(Integer.parseInt(scanner.next())); 
     studentList[counter].setCountry(scanner.next());  
     counter++; 
    } 

您检查scanner.hasNext()只有一次,然后调用scanner.next()几次。如果任何非空输入行的元素少于预期,这将抛出NoSuchElementException

OTOH检查hasNext()在每个字段分配之前非常尴尬。另一种可能是使用String.split。这会产生一个String[],您可以在尝试初始化新学生对象之前检查其长度以确保所有字段都存在。

+0

它似乎我的解析器不能正常工作。它只解析学生ID。我不知道代码 – 2012-03-20 17:37:55

+0

+1是因为提到Jon Skeet似乎错过了什么:-) – TheBlastOne 2012-03-20 17:39:14

+0

@cengizkandemir如果你的文件只包含一个学生ID,它会失败。 – TheBlastOne 2012-03-20 17:40:53

0

随着

Student studentList[] = new Student(10); 

你只是建立学生类型的数组,大小10的该数组包含学生的10篇参考文献,尚未定义的每个引用(这将是一个零)。

之前调用的学生参考的任何一套方法,实例化这样

studentList[counter] = new Student(); 

的对象,这样你的代码可能成为像

if (scanner.hasNext()) { 
     studentList[counter] = new Student(); 
     studentList[counter].setStudentNumber(scanner.next());