【Java】Serializable序列化

本文介绍了Java序列化的基本概念,包括将对象转换为字节序列的序列化和反序列化过程。它常用于对象持久化、网络传输和存储。Java中的Serializable接口用于标记可序列化类,ObjectOutputStream和ObjectInputStream分别用于对象的序列化和反序列化。serialVersionUID用于版本控制,transient关键字可使属性在序列化时被忽略。文章还讨论了自定义序列化方法及Externalizable接口的使用,并给出了示例。
摘要由CSDN通过智能技术生成

概念

定义

  • 序列化

将对象转换为字节序列的过程

  • 反序列化

将字符序列转换成对象的过程

用途

  • 将内存中的对象持久化到硬盘中, 并之后能再次从磁盘中读取.

如web服务器中的会话session对象都要存储在内存中, 如果某一时间段session对象过多, 则会导致服务器内存不够用的情况, 这时可以借助序列化暂时将一部分session序列化存储到硬盘中, 等到需要时再取出.

  • 将内存中的对象通过网络进行传输.

前后端的交互中, 后端想要向前端发送一个用户的User类的对象时, 可以使用序列化将对象转换成字符串进行传输. 前端接收到字符串后进行解析, 即可获得对象相应属性的信息.

  • 使用redis存储对象

项目中自己定义的对象不属于redis的数据类型, 无法直接用redis存储, 所以要使用redis存储对象或其他数据类型时需要将对象序列化成字符串后再进行存储

JDK类库Serializable

Serializable是JDK类库中的一个接口, 它用来标记一个类可以被实例化, 内部没有任何需要实现的方法.

java.io.ObjectOutputStream: 对象的输出流
调用它的writeObject(Object obj)方法可以将obj对象序列化, 得到的字节序列写到一个目标输出流中

java.io.ObjectInputStream: 对象的输入流
调用它的readObject()方法可以读取流中的字节序列, 并将其反序列化成为一个对象返回.

serialVersionUID

所有实现了Serializable接口的类都会有的默认的静态变量, 用来标记类的序列化版本号, 用来版本控制.

如果没有显示定义serialVersionUID的时候, java序列化机制会根据Class自动生成一个serialVersionUID, 如果Class文件发生变化, 则serialVersionUID会相应的改变.

  • 可以自认定义, 一般默认版本号为1L

  • 也可以根据包名, 类名, 方法和属性等多个因素计算得出, 生成一个复杂的唯一的哈希字段.

private static final long serialVersionUID = 8234096359105532505L;

序列化对象时, 序列化的结果里会保存当前对象所在类的serialVersionUID, 反序列化时会检查类中的UID与返序列化对象的UID是否一致, 不一致则不允许序列化. 并抛出异常

可以用idea自动生成
在setting中设置没有serialVersionUID时警告

在这里插入图片描述

在类名出现警告时可以选择自动生成

在这里插入图片描述

transient

为了提高效率, 类中某些属性在对象序列化时是没有必要被保存的, 或是需要被忽略的, 这时可以用transient关键字来标记这些属性不被序列化.
被static和transient修饰的属性都不会被序列化.
例如一些流stream, 在反序列化之后可能已经不存在了. 或者需要重新打开, 这个属性就可以用transient标记不被序列化
被标记的transient属性在反序列化的时候会被赋值为默认的初值, 如int赋值0, 对象赋值null等

序列化方法

现有一个Person类实现了Serializable接口

- 该Persson类只实现了Serializable

则直接用Object输入流或输出流的writeObject(Object obj)或readObject()方法直接对Person类的非transient属性进行序列化和反序列化

- 该Person实现了Serializable,并且在类中重新定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out)方法

在序列化和反序列化时会调用类中的readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out)方法.

- 该Person类实现了Externalnalizable接口

则类中必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法, 并通过该方法进行序列化.

示例

Person

class Person implements Serializable {
   

    String id;
    String name;
    Integer age;

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

    public Person() {
   
    }

    public String getId() {
   
        return id;
    }

    public void setId(String id) {
   
        this.id = id;
    }

    public String getName() {
   
        return name;
    }

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

    public Integer getAge() {
   
        return age;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值