首页 > 其他分享 >序列化和反序列化

序列化和反序列化

时间:2022-11-28 17:46:04浏览次数:45  
标签:Java 对象 object byte 序列化 serialVersionUID

一、序列化:将Java对象转换成字节流的过程

  • 序列化过程:是指把一个Java对象变成二进制内容,实质上就是byte[]。因为序列化后可以把byte[]保存到文件中,或者把byte[]通过网络传输到远程(IO),如此就相当于把java存储到文件或者通过网络传输出去了

 

二、反序列化:将字节流转换成Java对象的过程

  • 反序列化过程:把一个二进制内容(也就是byte[])变回Java对象。有了反序列化,保存到文件中的byte[]又可以“变成”java对象,或者从网络上读取byte[]并把它“变成”Java对象。

 

三、为什么需要序列化

当两个进程进行远程通信时,可以互相发送各种类型的数据(包括文本、图片、音频、视频等),而这些数据都会以二进制序列的形式在网络上传送。当两个Java进程进行通信时,需要Java序列化和反序列化实现进程间的对象传送,换句话说,一方面,发送方需要把这个 Java 对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出 Java 对象。

作用:

  1. 实现了数据的持久化,序列化可以把数据永久地保存在硬盘上(通常存放在文件里)

  2. 通过序列化以字节流的形式使对象在网络中进行传递和接收

  3. 通过序列化在进程间传递对象

注意事项:

1、某个类可以被序列化,则其子类也可以被序列化。

2、声明为static和transient的成员变量,不能被序列化。static成员变量是描述类级别的属性,transient表示临时数据

3、一个 Java 对象要能序列化,必须实现java.io.Serializable接口。因为序列化是一个非常复杂的算法操作,所以java官方给我们写好了,但是使用的方式很特殊,java底层写好了序列化操作,但是官方并不确定”你的Java对象”是否需要序列化,因此官方搞了一个”接口标记”的操作。如果对象需要底层的序列化操作,就实现Serializable 接口,如果对象不需要底层的序列化操作,就不需要实现Serializable 接口

  Serializable 接口源码:

public interface Serializable {
}

  Serializable 没有定义任何方法,它是一个空接口。这样的空接口称为“标记接口”(Marker Interface),其存在的意义就是为了添加标记

 

四、序列化方式

默认情况下,JVM负责编写和读取可序列化对象的过程,序列化/反序列化功能通过对象流类的以下两种方法公开

  •  ObjectOutputStream.writeObject(object):将可序列化的对象写入输出流
  •  ObjectInputStream.readObject():从输入流读取,构造并返回一个对象
package com.chenly.serialize;

import com.chenly.serialize.bean.Score;
import java.io.*;

/**
 * @author: chenly
 * @date: 2022-11-25 17:14
 * @description:
 * @version: 1.0
 */
public class Test  {

    public static void main(String[] args) {
        Score score1 = Score.builder()
                .className("一班")
                .stuName("张三").course("生物").score(90).build();
        Test test = new Test();
        //序列化
        byte[] bytes= test.serialize(score1);
        //反序列化
        Object object = test.deserialize(bytes);
        System.out.println("反序列化输出:"+object);

    }


    private byte[] serialize(Object object) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream=null;
        try {
            objectOutputStream = new ObjectOutputStream(out);
            //序列化
            objectOutputStream.writeObject(object);
            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private Object deserialize(byte[] bytes) {
        InputStream in = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream=null;
        try {
            objectInputStream = new ObjectInputStream(in);
            //反序列化
            Object object=objectInputStream.readObject();
            return object;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


}

 

五、serialVersionUID常数

  • serialVersionUID是一个常数,用于标识可序列化类的版本,JVM在反序列化过程中检查此常数,如果正在反序列化的对象的serialVersionUID与类中指定的序列号不同,则JVM抛出InvalidClassException。
  • serialVersionUID 是可选的,如果不显式声明,Java编译器将自动生成一个,自动生成的serialVersionUID 是基于类的元素(成员变量、方法和构造函数等)计算的。如果这些元素一旦发生更改,serialVersionUID 也将更改。

  例如:定义了一个Student类,未显示声明serialVersionUID ,序列化后保存到文件中,之后在Student类中新增一个字段address,此时将文件中的Student对象反序列化就会抛异常,无法反序列化回来了。如果定义了serialVersionUID ,即使在Student里加了一个属性,但还是可以反序列化回来的,只是新加的那个属性值为null而已

 

标签:Java,对象,object,byte,序列化,serialVersionUID
From: https://www.cnblogs.com/kiko2014551511/p/16932750.html

相关文章

  • DRF序列化
    DRF序列化目录DRF序列化序列化组件序列化序列化类的字段类型序列化类型的选项参数反序列化put反序列化需要实现序列器类父类的update方法反序列化校验read_only和write_on......
  • Newtonsoft.Json null值不序列化
    varjSetting=newJsonSerializerSettings{NullValueHandling=NullValueHandling.Ignore};varjson=JsonConvert.SerializeObject(response,Formatting.Indented,j......
  • mysql jdbc反序列化利用
    参考资料https://www.anquanke.com/post/id/203086按照资料描述搭建环境,注意,如果使用8.0.28版本的mysql,服务端MySQL_Fake_Server会报错(ValueError('45isnotavalidCha......
  • Java 序列化工具
    一、Java自带的序列化Java提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据......
  • Android 序列化框架 Gson 原理分析,可以优化吗?
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。前言大家好,我是小彭。Gson是Google推出的JavaJson解析库,具有接入成本低、使用便捷、功......
  • 23.几种序列化方式
    什么是序列化关于序列化相信大家都很了解,在Java中我们经常就可以看到很多实体类或者 POJO 都会实现 Serializable 接口,有了解过 Serializable 接口的小伙伴应该都......
  • Fastjsonfan反序列化(一)
    前置知识Fastjson是一个Java库,可以将Java对象转换为JSON格式,当然它也可以将JSON字符串转换为Java对象。Fastjson可以操作任何Java对象,即使是一些预先存在......
  • Java实体类为什么需要序列化和反序列化
    最近在学习做微服务的项目,在参考他人的微服务项目时,发现数据库表所对应的实体类都会实现Serializable接口,以往做的项目中并没有遇到过,也没有实现过这个接口,所以好奇实体类......
  • 序列化工具类
     importio.protostuff.LinkedBuffer;importio.protostuff.ProtostuffIOUtil;importio.protostuff.Schema;importio.protostuff.runtime.RuntimeSchema;importo......
  • Android 进程之间复杂的数据类型传输为啥一定需要序列化
    Android进程之间复杂的数据类型传输为啥一定需要序列化Linux特性Android系统都是基于Linux系统实现的,而这里Linux运行的时候,都是有进程隔离机制的。Linux采用了虚拟内......