前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >对象序列化流与反序列化流

对象序列化流与反序列化流

作者头像
兰舟千帆
发布2022-07-16 13:32:48
发布2022-07-16 13:32:48
55700
代码可运行
举报
运行总次数:0
代码可运行

对象序列化流与反序列化流

什么是序列化与反序列化

=java序列化,就是指吧java对象转换为字节序列的过程。而反序列自然就是将字节对象恢复为java对象。==

这样做的意义在哪呢?对象进行序列化,会转换为字节流,这样在网络上传输,或者是进行保存为本地文件都是非常方便的。反序列很明显就是进行对象的重构。

其实你可以和通信联系在一起。网络上的文本,图片,视频,音频都是通过二进制进行传输的,我们的java所创建的对象在传输的时候也应该进行序列化,转换为字节流,然后通过网络,io传入,当我们的对象序列传输完成后,对方进行反序列化,就可以读取到数据内容。

对象序列化流( ObjectOutputStream)

api对这个类有很多的说明,主要说明

public class ObjectOutputStreamextends OutputStreamimplements ObjectOutput, ObjectStreamConstants

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。

看一下简单使用

首先我们需要一个对象类

代码语言:javascript
代码运行次数:0
运行
复制
package io_demo;

import java.io.Serializable;

public class Student implements Serializable {

    private String sid;
    private String name;
    int age;

    private String address;
    public Student()
    {

    }

    public Student(String sid, String name, int age, String address) {
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    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;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

然后测试主类

代码语言:javascript
代码运行次数:0
运行
复制
package io_demo;

import java.io.*;

public class IoDemo_23 {
    //对象序列化流
//    构造方法
   // ObjectOutputStream(OutputStream out)
    public static void main(String args[]) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\java_doc\\src\\io_demo\\jgdabc.txt"));
        Student s = new Student("001","刘备",28,"汉中");
        oos.writeObject(s);//将对象序列化()
        oos.close();
    }
}

为什么Student需要实现Serializable,api有说明

只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。

为什么没有具体实现?

因为这个接口本身没有具体实现,我们不要要实现什么,这个只是作为一个标识而已。

对象反序列化流(.ObjectInputStream)

public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants

说明如下

ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象。 ObjectOutputStream和ObjectInputStream可以分别为与FileOutputStream和FileInputStream一起使用的对象图提供持久性存储的应用程序。 ObjectInputStream用于恢复先前序列化的对象。 其他用途包括使用套接字流在主机之间传递对象,或者在远程通信系统中进行封送和解组参数和参数。

首先还是原来的Student对象类

代码语言:javascript
代码运行次数:0
运行
复制
package io_demo;

import java.io.Serializable;

public class Student implements Serializable {

    private String sid;
    private String name;
    int age;

    private String address;
    public Student()
    {

    }

    public Student(String sid, String name, int age, String address) {
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    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;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

对的,你虽然是从文件中读取,但是如果你不使用构建的对象的话。是绝对无法成功进行反序列化的。

主要的测试代码

代码语言:javascript
代码运行次数:0
运行
复制
package io_demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

//反序列化ObiectreadObject() 进行读取来反序列化
public class IoDemo_24 {
    public static void main(String args[]) throws IOException, ClassNotFoundException {
        //实现对象反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\java_doc\\src\\io_demo\\jgdabc.txt"));
        Object o = ois.readObject();
        Student s = (Student)o;
        System.out.println(s.getName()+","+s.getAge());
        ois.close();


    }
}

这样感觉有时候很像加密与解密的样子。

如果在反序列话的时候原来对象类有修改?

我现在就修改一个属性。我让age属性权限有所变化,变为私有属性

**结果反序列化就报错了,为什么?你看报错 **

再清晰一点就是

local class incompatible: stream classdesc serialVersionUID = -8624680451455869930, local class serialVersionUID = 6474701452341618882

serialVersionUID是什么?(为什么修改对象类会反序列化失败?)

serialVersionUID是序列化的时候会生成的一个的版本标识,。当我们对对象进行修改后,那么这个序列化的版本标识的值就会与之前的不一样了。这样会导致字节流的版本标识与本地的版本标识不一样,不一样就会反序列化失败。

解决修改对象类修改反序列化失败的问题

我们就自己定义一个常量。让这个版本标识符不再变化

注意,一定是在对象类中,不是在测试类。

不想让某些属性被序列化?

这样就可以

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 对象序列化流与反序列化流
    • 什么是序列化与反序列化
    • 对象序列化流( ObjectOutputStream)
    • 对象反序列化流(.ObjectInputStream)
    • 如果在反序列话的时候原来对象类有修改?
      • serialVersionUID是什么?(为什么修改对象类会反序列化失败?)
      • 解决修改对象类修改反序列化失败的问题
      • 不想让某些属性被序列化?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档