2016-11-29 55 views
1
package edu.uga.cs1302.gui; 

import javax.swing.SwingUtilities; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 

public class StudentMain { 
    public static void main(String[] args) { 
     // this is inside a "lambda" Runnable 

     FileOutputStream fos; 
     try { 
      Student a = new Student("C", "H", 1234, "12-11-1937", "UGA"); 
      fos = new FileOutputStream("StudentsList.dat"); 
      ObjectOutputStream oos = new ObjectOutputStream(fos); 
      a.storeObject(oos); 
      System.out.println("success"); 
      FileInputStream fis = new FileInputStream("StudentsList.dat"); 
      ObjectInputStream ois = new ObjectInputStream(fis); 
      Student b = new Student("B", "H", 8888, "10-22-1936", "UNC"); 
      b.retrieveObject(ois); 
      System.out.println(b.toString()); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

學生班級的FileInputStream錯誤的Java:讀取文件錯誤

package edu.uga.cs1302.gui; 

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
import java.text.ParseException; 

public class Student extends Person implements Serializable{ 

protected String college; 
private static final long serialVersionUID = -5047600810798119921L; 
public Student(String firstname, String lastname,int ID, String DOB1, String college) throws ParseException{ 
    super(firstname, lastname,ID, DOB1); 
    this.college=college; 
} 
public void storeObject(ObjectOutputStream out) throws IOException{ 
    out.writeObject(this); 
    out.flush(); 
} 
public void retrieveObject(ObjectInputStream in) throws IOException,  ClassNotFoundException, ParseException{  
      Student temp = (Student) in.readObject(); 
     System.out.println(temp.toString()); 
     this.setFirst(temp.getFirst()); 
     this.setLast(temp.getLast()); 
     this.setID(temp.getID()); 
     this.setDOB(temp.getDOB()); 
     this.setCollege(temp.getCollege()); 

} 
public String getCollege(){ 
    return college; 
} 
public void setCollege(String college){ 
    this.college= college; 
} 
public String toString(){ 
    String student = super.getID() + " "+super.getFirst()+" "+super.getLast()+" "+super.getDOB()+" ["+college+"]"; 
    return student; 
} 
} 

Person類

package edu.uga.cs1302.gui; 

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

public class Person { 

public String first; 
public String last; 
public Date date1; 
public int ID; 
public String DOB; 

public Person(String firstname, String lastname,int ID, String DOB1) throws ParseException{ 
    this.first=firstname; 
    this.last=lastname; 
    if(ID>999&&ID<10000){ 
     this.ID = ID; 
    } 
    SimpleDateFormat simple = new SimpleDateFormat("MM-dd-yyyy"); 
    Date date = simple.parse(DOB1); //must parse to get data 
    this.date1 = date; 
    this.DOB = DOB1; 
    //this.DOB = DOB; 
} 
public String getFirst(){ 
    return first; 
} 
public String getLast(){ 
    return last; 
} 
public String getDOB(){ 
    return DOB; 
} 
public int getID(){ 
    return ID; 
} 
public void setFirst(String first){ 
    this.first = first; 
} 
public void setLast(String last){ 
    this.last = last; 
} 
public void setDOB(String DOB1) throws ParseException{ 
    SimpleDateFormat simple = new SimpleDateFormat("MM-dd-yyyy"); 
    Date date = simple.parse(DOB1); //must parse to get data 
    this.date1 = date; 
} 
public void setID(int ID){ 
    this.ID = ID; 
} 
public String toString(){ 
    SimpleDateFormat sim = new SimpleDateFormat("MM-dd-yyyy"); 
    String date = sim.format(this.date1);//formats to simple format 
    String person = ""+ ID + " "+first+" "+last+" "+date; 
    return person; 
} 


} 

錯誤

success 
java.io.InvalidClassException: edu.uga.cs1302.gui.Student; no valid constructor 
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:150) 
at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:790) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) 
at edu.uga.cs1302.gui.Student.retrieveObject(Student.java:25) 
at edu.uga.cs1302.gui.StudentMain.lambda$0(StudentMain.java:30) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756) 
at java.awt.EventQueue.access$500(EventQueue.java:97) 
at java.awt.EventQueue$3.run(EventQueue.java:709) 
at java.awt.EventQueue$3.run(EventQueue.java:703) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 

一些未知的原因,我的FileInputStream是行不通的。該文件正在創建,所以我知道FileOutputStream正在工作。但是,在閱讀文件時,它無法破譯意義。

+2

嘗試添加一個空的構造函數'Student'類。 – Eric

+0

你可以在一個空的構造函數中,但是如果適用,你可能想使用Person的構造函數,因爲整個繼承點就是擴展已經存在的元素。 – DejaVuSansMono

+0

您添加了異常跟蹤,這很好。現在你必須看看它。當你這樣做時,你會發現問題不是* FileInputStream而是ObjectInputStream。當你查看[InvalidClassException]的[docs](http://docs.oracle.com/javase/8/docs/api/java/io/InvalidClassException.html)時,你會知道在你的目錄中尋找什麼碼。或者你可以關注* Erik Kralj *的建議。 – kdgregory

回答

1

如果你有一個不帶參數的構造函數非序列化類,你可以很容易得到InvalidClassException期間序列化,然後反序列化任何擴展這個類的類。 此問題的解決方案之一是使用序列化代理模式。

要實現它,您必須在實現Serializable的類中創建一個靜態嵌套的SerializationProxy類。 SerializationProxy將表示封閉類的邏輯狀態,並將在序列化期間寫入字節流而不是原始實例,在反序列化期間將創建原始類的實例,該實例取代它在對象圖中的位置。

https://dzone.com/articles/serialization-proxy-pattern

http://blog.codefx.org/design/patterns/serialization-proxy-pattern/

0

您需要擁有所有對象的可序列化。只需實現Serializable for Person以便它可以被寫入。事實上,您應該標記您的基類是可序列化的,然後由於繼承,子類將自動被序列化。

成功 1234 CH 1937年12月11日[UGA] 1234 CH 1936年10月22日[UGA]

+0

爲什麼我需要5個字符串參數?截至目前,我有4個字符串參數和1個整數參數。 @hhafeez –

+0

然後更正此行 – hhafeez

+0

學生a =新生(「C」,「H」,1234,「12-11-1937」,「UGA」); 在這裏你傳遞5個字符串參數。但是你的實例期望4.你傳遞一個額外的論據。 – hhafeez