A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 水煮牛蛙 中级黑马   /  2018-4-23 15:37  /  1062 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2018-4-25 16:44 编辑

类的序列化与反序列化 (解决类版本号不同异常)


/*
* 解决对实现序列化接口出现黄色警告问题:
*                 下边这个案例中,对象输出流将就有两个属性(name,age)的Person类的对象写入文件,写入文件后我们对
*                 Person类进行了更改,往类中加入了一个height(身高属性),这时将文件内的Person类的对象再读取出来,'
*                 就出现了问题(存入对象与所属类出现了不一样)系统抛出"java.io.InvalidClassException"异常,
*                 是因为该类的版本号与读取的类的对象的序列版本号就不匹配造成的.
* 解决办法:
*                 1.在类中添加序列化版本号,将该的序列号版本号创建为不可变得
*                 2.类的序列化版本号固定后,将该类的对象存入文件后,该类发生变化时,将该类的对象读取出来后,
*                       就不会在抛出"java.io.InvalidClassException"异常了
*                 3.当类的属性变多时,从文件中读取到的对象也具有该属性但是为默认值(0或者null);
*                      当类的属性变少时,从文件中读取到的对象也就访问不到缺少的属性了;
*
* 在类中自动生成序列化版本号:
*                将鼠标放到标黄线的类名处,点击add generated serial version ID
*                                   
*                 
*                 
* java.io.InvalidClassException异常出现原因:
*                         1.该类的序列版本号与从流中读取的类描述符的版本号不匹配
*                        2.该类包含未知数据类型
*                        3.该类没有可访问的无参数构造方法
*
*序列化与反序类化:
*        1. 在java中,类的序列化和反序列化是由jvm实现,当然,不同的jvm可能有不同的实现方式.
*        一个类,实现Serializable接口之后,就代表开发者允许此类可以被序列化和反序列化,jvm就获得了序列化和
*        反序列化的授权.如果没有实现Serializable,而直接进行类的序列化操作,jvm报出异常.
*        Serializable是一个标识接口,没有任何带实现的方法;
*        2.java序列化机使用名称为serialVersionUID的long型字段来标志类的版本.
*        3.序列化对象时,jvm会把seriaVersionUID的值写到类的序列化数据中;
*        4.反序列化时,jvm会把数据中的seriaVersionUID与本地相应类的serialVersionUID进行比较,如果值不相同
*          (意味着类的版本不同),那么报异常InvalidDastException,即:类版本不对应,不能进行反序列化.如果类版本相同,
*          则可以进行反序列化.
*
*
*
*/
//定义一个人类
class Person implements Serializable{
        /**
         * 序列化版本号,生成为不可变的
         */
        private static final long serialVersionUID = 3386607534178686209L;
        String name;
        int age;
        int height;
        public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
        }
        @Override
        public String toString() {
                return "Person [name=" + name + ", age=" + age + "]";
        }
        
}

//测试类
public class 设置类的序列化版本号 {

        public static void main(String[] args) throws IOException, ClassNotFoundException {
//                写出对象();
                读取对象();
               
               
        }
        private static void 读取对象() throws IOException, FileNotFoundException, ClassNotFoundException {
                //创建对象输入流 的对象
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ObjectOutputStream"));
                //读取对象
                Object obj = ois.readObject();
                //打印对象
                Person p = (Person)obj;
                System.out.println(p.name);
//                System.out.println(p.age);
                System.out.println(p.height);
        }
        //将人类对象写入文件
        private static void 写出对象() throws IOException, FileNotFoundException {
                //创建对象输出流的对象
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ObjectOutputStream"));
                //创建对象
                Person p = new Person("pingguo",15);
                //写出对象
                oos.writeObject(p);
                //释放资源
                oos.close();
        }

}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马