2012-03-20 58 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());