【问题标题】:Error in : java.io.InvalidClassException错误:java.io.InvalidClassException
【发布时间】:2012-04-27 04:35:39
【问题描述】:

我正在解决这个问题,但遇到此错误无法解决该错误:

这是我的课:

package stdaccmdmngmt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JOptionPane;

/**
 *
 * @author princess
 */
public class Student1 implements Serializable {

public static Set<Student1> listOfStudents = new HashSet<Student1>();    
public static File outFile = new File("StudentRegistry.dat"); 

// Data memebers 
private String studentID;
private String name;
private Date dateOfReg;

//Constructor 
Student1(String number,String name)
{
this.studentID = number;
this.name = name;
dateOfReg = new Date(); 
}


public String getName()
{
return name;
}

public String getStudentID()
{
return studentID;
}

public Date getDateOfReg()
{
return dateOfReg;
}

public void register() throws FileNotFoundException, IOException, ClassNotFoundException    
{ 
Set<Student1> sss = new HashSet<Student1>();    
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(outFile));
oos.writeObject(sss);
oos.close();      
}

public static HashSet<Student> getListOfStudents() throws FileNotFoundException, IOException, ClassNotFoundException
{
HashSet ss;
File inFile = new File("StudentRegistry.dat");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(inFile));
Set<Student> aNewSet = (HashSet<Student>) ois.readObject();
return  (HashSet<Student>) aNewSet;
}

public static Student getStudentbyID(String a) throws FileNotFoundException, IOException, ClassNotFoundException
{
Set<Student> aNewSet = new HashSet<Student>();
aNewSet = Student.getListOfStudents();
Student result = null;

for (Student x :aNewSet)
{
        if (x.getStudentID().equalsIgnoreCase(a))
        {
             result = x;
             break;
        }
    }  
    if (result == null)
    {
        JOptionPane.showMessageDialog(null, "Apartment not found");
    }
    return result;    

}

    @Override
public String toString()
{
// include the code to retrieve assigned apartment    
return "Name: " + name +" StudentID: "+ studentID + " Registered On: " + dateOfReg;
}


    @Override
public boolean equals(Object another)
{
Student1 stud = (Student1)another;
return this.name.equals(stud.name)&& this.studentID.equals(stud.studentID);
}

    @Override
public int hashCode()
{
int hash = name.hashCode();
return hash;

}    
}

这是测试类:

package stdaccmdmngmt;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author princess
 */
public class Test {

public static void main (String[]args) throws FileNotFoundException, ClassNotFoundException, IOException
{        
Student1 s = new Student1("12345","Sasha");   
        try {
            s.register();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }

Set<Student> nnn;
 nnn = Student.getListOfStudents();
for (Student x : nnn)

    System.out.println(x.toString());      

}

}
 * @author princess
 */
public class Student1 implements Serializable {

public static Set<Student1> listOfStudents = new HashSet<Student1>();    
public static File outFile = new File("StudentRegistry.dat"); 

// Data memebers 
private String studentID;
private String name;
private Date dateOfReg;

//Constructor 
Student1(String number,String name)
{
this.studentID = number;
this.name = name;
dateOfReg = new Date(); 
}


public String getName()
{
return name;
}

public String getStudentID()
{
return studentID;
}

public Date getDateOfReg()
{
return dateOfReg;
}

public void register() throws FileNotFoundException, IOException, ClassNotFoundException    
{ 
Set<Student1> sss = new HashSet<Student1>();    
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(outFile));
oos.writeObject(sss);
oos.close();      
}

public static HashSet<Student> getListOfStudents() throws FileNotFoundException, IOException, ClassNotFoundException
{
HashSet ss;
File inFile = new File("StudentRegistry.dat");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(inFile));
Set<Student> aNewSet = (HashSet<Student>) ois.readObject();
return  (HashSet<Student>) aNewSet;
}

public static Student getStudentbyID(String a) throws FileNotFoundException, IOException, ClassNotFoundException
{
Set<Student> aNewSet = new HashSet<Student>();
aNewSet = Student.getListOfStudents();
Student result = null;

for (Student x :aNewSet)
{
        if (x.getStudentID().equalsIgnoreCase(a))
        {
             result = x;
             break;
        }
    }  
    if (result == null)
    {
        JOptionPane.showMessageDialog(null, "Apartment not found");
    }
    return result;    

}

    @Override
public String toString()
{
// include the code to retrieve assigned apartment    
return "Name: " + name +" StudentID: "+ studentID + " Registered On: " + dateOfReg;
}


    @Override
public boolean equals(Object another)
{
Student1 stud = (Student1)another;
return this.name.equals(stud.name)&& this.studentID.equals(stud.studentID);
}

    @Override
public int hashCode()
{
int hash = name.hashCode();
return hash;

}    
}

.......................

我收到了这个错误:

run:
Exception in thread "main" java.io.InvalidClassException: stdaccmdmngmt.Student; local class incompatible: stream classdesc serialVersionUID = -3040096452457271695, local class serialVersionUID = -4849175799723926283
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
    at java.util.HashSet.readObject(HashSet.java:291)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
    at stdaccmdmngmt.Student.getListOfStudents(Student.java:76)
    at stdaccmdmngmt.Test.main(Test.java:34)
Java Result: 1
BUILD SUCCESSFUL (total time: 3 seconds)

有什么帮助吗?

提前致谢:)

【问题讨论】:

    标签: java exception hash iostream


    【解决方案1】:

    您遇到过使用 Java 序列化的一个陷阱是持久性框架(与用于通信的数据格式相反)。您保留了学生数据,然后更改了 Student 类。现在,当您尝试读取持久数据时,它会失败,因为基本上,该类的两个版本不匹配。如果您在学生类上手动指定了serialVersionUID,则序列化框架不会在读取数据文件时卡住(反正不会马上)。

    但根本问题是序列化与持久性不同 - 如果您想保存学生数据,那么您需要选择一个框架来执行此操作,以减少类文件不兼容性的影响。我建议先保存为 CSV 文件,如果项目的复杂性需要,我也建议先看看数据库解决方案。


    * 编辑 *

    作为临时修复,您可以尝试将类重命名为 Student 并将 serialVersionUID 设置为序列化框架所期望的。这不是一个可靠的修复,它取决于自您创建文件以来该类发生了多少变化:

    public class Student implements Serializable {
        public static final long serialVersionUID = -3040096452457271695L;
    
        // ...
    }
    

    由于您的项目需要使用对象输出流,我建议在您的Student 类上实现Externalizable 接口,并实现将其读/写到对象输出流的方法:

    public class Student implements Serializable, Externalizable {
        public static final long serialVersionUID = -3040096452457271695L;
        // ...
    
       @Override
       public void writeExternal(ObjectOutput out) throws IOException {
          out.writeUTF(getStudentID());
          out.writeUTF(getName());
          // etc
       }
    
       @Override
       public void readExternal(ObjectInput in) throws IOException,
             ClassNotFoundException {
          setStudentID(in.readUTF());
          setName(in.readUTF());
          // etc
       }
    
       // ...
    }
    

    【讨论】:

    • 我会选择数据库解决方案,但根据我被问到的问题(是的,这是一项任务!)我必须使用 ioObjectStream。有什么简单的方法可以修复错误?
    • 我在 Netbeans 中打开了一个新项目并复制了 EXACT 代码。 (毕竟这只是一节课)。反正。现在不知何故没有创建新文件,它给了我以下错误:pr 27, 2012 9:55:01 AM hostelmanagement.HostelManagement main SEVERE: null java.io.FileNotFoundException: Student.dat(系统找不到指定的文件) 在 java.io.FileInputStream.open(Native Method) 在 java.io.FileInputStream.(FileInputStream.java:106) 在 hostelmanagement.Student.getListOfStudents(Student.java:86)
    • 在 hostelmanagement.HostelManagement.main(HostelManagement.java:42) Java Result: 1 BUILD SUCCESSFUL (total time: 3 seconds) .. 我做错了什么,它是相同的代码复制。
    【解决方案2】:

    取自 Javadoc:

    http://java.sun.com/j2se/1.4.2/docs/api/

    公共类 InvalidClassException 扩展 ObjectStreamException

    当序列化运行时检测到以下问题之一时抛出 有一个类。

    • 类的序列号与类的不匹配 从流中读取的描述符
    • 该类包含未知数据类型
    • 该类没有可访问的无参数构造函数

    【讨论】:

    • 您能否详细说明一下这种解释对 OP 有何帮助?
    • 这里的座右铭不是帮助 OP 变得更加自给自足吗?
    猜你喜欢
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 2015-07-21
    • 2013-12-08
    • 2020-01-06
    相关资源
    最近更新 更多