对象序列化流

对象序列化

  • 概述
  1. 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
  2. 使用一个字节序列表示一个对象, 该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
  3. 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息。当然,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。

对象序列化流

  • 概述
    将java对象的原始数据和图形写入文件,实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。

  • 构造方法

    构造方法描述
    ObjectOutputStream​(OutputStream out)创建一个对象序列化流
    常用方法描述
    void writeObject​(Object obj)将指定的对象写入ObjectOutputStream
    //学生类
    class Student implements Serializable {
        String name;
        int age;
        public Student() {
        }
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    //测试类
    public class Demo {
        public static void main(String[] args) throws IOException {
            //创建学生对象
            Student s1 = new Student("王磊",15);
            //创建对象序列化流
            ObjectOutputStream oos =
                    new ObjectOutputStream(new FileOutputStream("1.txt"));
            //对象写入文件
            oos.writeObject(s1);
            oos.close();
        }
    }
    ---*---
    输出结果:
    在1.txt文件中写入了:
     sr com.Zh.Student都貒r帚 I ageL namet Ljava/lang/String;xp   t 鐜嬬
    

    注意:一个对象要想被序列化,该对象的数据类型必须实现 Serializable 接口(可序列化接口)。该接口不需要重写任何方法,仅用于标识该类可以序列化和反序列化。

对象反序列化流

  • 概述
    ObjectInputStream对先前使用ObjectOutputStream编写的原始数据和对象进行反序列化。

  • 构造方法

    构造方法描述
    ObjectInputStream​(InputStream in)创建一个从指定的InputStream读取的ObjectInputStream
    常用方法描述
    Object readObject()从ObjectInputStream中读取一个对象
    public class Demo {
        public static void main(String[] args) throws IOException,  ClassNotFoundException {
            //创建学生对象
            Student s1 = new Student("王磊",15);
            //创建对象序列化流
            ObjectOutputStream oos =
                    new ObjectOutputStream(new FileOutputStream("e:\\360sd\\1.txt"));
            //对象写入文件
            oos.writeObject(s1);
            oos.close();
            
            //创建对象反序列化流
            ObjectInputStream ois =
                    new ObjectInputStream(new FileInputStream("e:\\360sd\\1.txt"));
            //读取对象
            Object o = ois.readObject();
            Student s2 = (Student) o;
            System.out.println(s2.getName()+","+s2.getAge());
            ois.close();
        }
    }
    ---*---
    输出结果:
    王磊,15
    

    通过ObjectInputStream将ObjectOutputStream写入的对象通过readObject方法读取出来。

两个问题

  • 1.使用对象序列化流序列化了一个对象之后,如果修改了对象的类文件,读取数据会出现什么问题?为什么会出现这样的问题?
    • 序列化对象之后修改类文件,再读取数据会抛出InvaildClassException异常。因为序列化运行时会与每个可序列化的类关联一个版本号,serialVersionUID(序列化ID),在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否已加载与该序列化兼容的该对象的类。 也就是说当对象序列化或反序列化时都会默认隐性的为可序列化的类关联一个版本号,以验证序列化和反序列化的是兼容的类。而且版本号对类的细节十分十分敏感,可能因编译器实现而产生异常,所以可序列化类必须声明显式serialVersionUID值且必须为 static final long 类型:private static final long serialVersionUID = 42L;
  • 2.对象中的成员变量的 不想被序列化,用什么方法实现?
    • transient关键字修饰的成员变量不参与序列话。
    //学生类
    	class Student implements Serializable {
    	    private static final long serialVersionUID = 4L;
    	    String name;	
    	    transient int age;	//transient修饰的成员变量不参与序列化
    	    public Student() {
    	    }
    	    public Student(String name, int age) {
    	        this.name = name;
    	        this.age = age;
    	    }
    	}
    //测试类
    public class Demo {
        public static void main(String[] args) throws IOException,ClassNotFoundException  {
            writ();
            read();
        }
        public static void writ() throws IOException{
            //创建学生对象
            Student s1 = new Student("王磊",15);
            //创建对象序列化流
            ObjectOutputStream oos =
                    new ObjectOutputStream(new FileOutputStream("e:\\360sd\\1.txt"));
            //对象写入文件
            oos.writeObject(s1);
            oos.close();
        }
        public static void read() throws IOException,ClassNotFoundException{
            //创建对象反序列化流
            ObjectInputStream ois =
                    new ObjectInputStream(new FileInputStream("e:\\360sd\\1.txt"));
            //读取对象
            Object o = ois.readObject();
            Student s2 = (Student) o;
            System.out.println(s2.getName()+","+s2.getAge());
            ois.close();
        }
    }
    ---*---
    输出结果:
    王磊,0
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值