问答详情
源自:6-1 序列化基本操作

反序列化时抛出异常

抛出这个异常不知道是什么原因呀

Exception in thread "main" java.io.InvalidClassException: com.imooc.file.Student; local class incompatible: stream classdesc serialVersionUID = -1595130985977377714, local class serialVersionUID = -6276597220496795978

at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)

at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)

at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)

at com.imooc.file.ObjectSerialDemo.main(ObjectSerialDemo.java:21)


提问者:田同学 2017-05-07 20:02

个回答

  • gkenan
    2017-05-07 23:50:14
    已采纳

    serialVersionUID不一致,导致反序列化失败。

    当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class(它通过类名,方法名等诸多因素经过计算而得,理论上是一一映射的关系,也就是唯一的)自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释,等等),就算再编译多次,serialVersionUID也不会变化的。

    你的这种异常是因为序列化对象之后又修改了该对象(增加空格,换行,增加注释,等等),使其编译后的class文件发生变化,导致程序执行时认为序列化的对象和反序列化的对象不是一种对象进而抛出异常。

    如果你不希望程序因为serialVersionUID不同而反序列化失败,可以在实现java.io.Serializable接口的实体类中显示定义一个serialVersionUID的long常量(一般为1L),这样反序列化时就不会检查实体类是否改变了。

  • gkenan
    2017-05-08 20:02:13

    怪我没说清,这个long是这么定义的:

    private static final long serialVersionUID = 1L;

    直接定义long没用

  • 田同学
    2017-05-08 19:45:50


    package com.imooc.file;


    import java.io.Serializable;


    public class Student implements Serializable {

    private String stuno;

    private String stuname;

    private int stuage;

    long serialVersionUID = 1L;

    public Student(){

    }

    public Student(String stuno, String stuname, int stuage) {

    super();

    this.stuno = stuno;

    this.stuname = stuname;

    this.stuage = stuage;

    }



    public String getStuno() {

    return stuno;

    }

    public void setStuno(String stuno) {

    this.stuno = stuno;

    }

    public String getStuname() {

    return stuname;

    }

    public void setStuname(String stuname) {

    this.stuname = stuname;

    }

    public int getStuage() {

    return stuage;

    }

    public void setStuage(int stuage) {

    this.stuage = stuage;

    }



    @Override

    public String toString() {

    return 

    "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage=" + stuage + "]";

    }

    }




    package com.imooc.file;


    import java.io.FileInputStream;

    import java.io.ObjectInputStream;

    import java.util.ArrayList;


    public class ObjectSerialDemo {


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

    String file = "demo/obj.dat";

    //1、对象的序列化注意student类要实现serializable接口

    /*ObjectOutputStream oos = 

    new ObjectOutputStream(new FileOutputStream(file));

    Student stu = new Student("10001","张三",20);

    oos.writeObject(stu);

    oos.flush();

    oos.close();*/

    //反序列化

    ObjectInputStream ois = new 

    ObjectInputStream(new FileInputStream(file));

    Student stu = (Student)ois.readObject();

    System.out.print(stu);

    ois.close();

    }


    }