序列化和反序列化

序列化和反序列化

package oo;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * @author 45~
 * @version 1.0
 * 使用ObjectOutputStream,完成数据的序列化
 */
public class OutputStream_ {
    public static void main(String[] args) throws Exception {
        //序列化后保存的文件不是纯文本的,而是按照他的数据格式来保存
        //所以此处写.txt格式也没用
        String filePath = "e:\\data.datuuu";
        //创建序列化对象,由于是对文件进行操作,所以传入节点流FileOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
        //序列化数据到e:\data.dat
        //保存的数据实质上是个对象,要实现Serializable接口
        oos.writeInt(100);//能保存100,因为int在底层能够自动装箱成Integer,Integer实现了Serializable接口
        oos.writeBoolean(true);//以下均能自动装箱成包装类
        oos.writeChar('a');
        oos.writeDouble(9.5);
        //此处其实是将String放进去,String也是实现了Serializable接口的,所以可以序列化。
        oos.writeUTF("不教一日闲过也");//注意放字符串的方法是UTF,而非String
        //保存一个实现了序列化接口的对象
        oos.writeObject(new Dog("旺财",10));
        oos.close();
        System.out.println("数据保存完毕(序列化形式)");
    }
}


在这里插入图片描述

package II;
import oo.Dog;//输出的Dog即公有的,此处注意不在同一个包里要访问要做成共有的

import java.io.*;

/**
 * @author 45~
 * @version 1.0
 * 反序列化
 */

public class OObjectInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {//第二个是抛出类型转换异常
        //确定从哪个文件去读取进行反序列化
        String filePath = "E:\\data.datuuu";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        //读取顺序,即反序列化的顺序需要和(保存数据)序列化的顺序一致,否则一定会报异常。
        //因为序列化(保存)是按顺序来保存数据类型和值到文件里边的,而反序列化是将数据和类型又读到程序里边了。
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
        //dog的编译类型是Object,运行类型是Dog
        Object dog = ois.readObject();//读对象,底层会把Object转型成Dog
        System.out.println("运行类型=" + dog.getClass());
        System.out.println("dog信息="+dog);

        //如果需要调用Dog的方法,需要向下转型
        //需要我们将Dog类定义,拷贝到可以引用的位置,不管是不是在同一个包,只要能引用就行
        //比如是public类,虽然不在同一个包也可以引用,若引用不到是转换不了的
        /*Dog dog2 =(Dog)dog;向下转型会提示没有此名称
          "'oo.Dog' is not public in 'oo'. Cannot be accessed from outside package"
          说明要用此Dog方法原先的类定义需要拿过来
        */
        Dog dog2 =(Dog)dog;
        System.out.println(dog2.getName());//旺财
        //System.out.println(ois.readObject());//因为在读时底层会把Object进行转型成一只狗
        //关闭外层流,底层会自动关闭传入的字节流FileInputStream(即真正干活的节点流)
        ois.close();
        /*(1)运行出现“Exception in thread "main" java.io.InvalidClassException”无效类型异常,
        是因为Dog类出现在OO包里。即在进行转换时,II包里也应该有类的定义,这是必须的。
          (2)在进行反序列化时一定要把类拿到,若无程序是跑不起来的。
          (3)重要细节:如果类里边有方法,此处简单用Getter和Setter方法,
                      如果希望调用Dog类里的方法,那么需要向下转型
              Object dog = ois.readObject();//底层会把Object转型成Dog,
              虽然此处的运行类型是Dog,编译调方法dog.getName()通不过哦,Object类里没有此方法。

         */

    }
}

/*
//将Dog类拿过来
class Dog implements Serializable {
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //若序列化时不定义toString方法,显示"dog信息=oo.Dog@58372a00"
    //当定义了toString方法就需要重新执行一遍

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
*/

    /*运行报错“Exception in thread "main" java.io.InvalidClassException: oo.Dog;
    local class incompatible:
    stream classdesc serialVersionUID = 553920722521361545,
    local class serialVersionUID = 8155589668217606734”

    Dog拷贝过来后需要重新生成一下,因为不重新生成认为版本不是统一的,
    因为有序列化问题,所以先运行OutoutStream_.java序列化,再运行此反序列化。

    报错二:“Exception in thread "main" java.lang.ClassCastException:
            oo.Dog cannot be cast to II.Dog
	        at II.OObjectInputStream.main(OObjectInputStream.java:32)”
	        在序列化时已经将Dog的包写出来了,所以包要么保持一致,要么用序列化的方式来处理。

	        解决办法:将Dog类公有化拿到外面

 */

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值