java 序列化、反序列化

序列化:序列化是指将对象的状态信息转换为可以存储或传输的形式的过程

反序列化:将序列化后的数据(即字节序列)恢复为原始对象的过程

测试代码:

package com.tan.redis.controller;


import java.io.*;

public class SerializationExample {

    /**
     * 序列化
     * @param person
     * @param fileName
     */
    public static void serializePerson(Person person, String fileName) {
        try (FileOutputStream fileOut = new FileOutputStream(fileName);
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(person);
            System.out.println("序列化到:" + fileName);
        } catch (IOException i) {
            i.printStackTrace();
        }
    }

    /**
     * 反序列化
     */
    public static Person deserializePersonFromFile(String fileName) {
        Person person = null;
        try (FileInputStream fileIn = new FileInputStream(fileName);
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            // 读取对象并强制转换为Person类型
            person = (Person) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            // 处理异常,比如打印堆栈跟踪
            e.printStackTrace();
        }
        return person;
    }

    public static void main(String[] args) {
        Person person = new Person("Alice", 30);

        String fileName = "person.ser";
        serializePerson(person, fileName);
        System.out.println("反序列化 = " + deserializePersonFromFile(fileName));
    }
}

@AllArgsConstructor
@Data
class Person implements Serializable {

    private static final long serialVersionUID = 1L; // 用于版本控制

    private String name;
    private int age;
    
    //    private Integer id;

 	// 自定义序列化方法
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject(); // 序列化当前对象的非瞬态和非静态字段
        // 可以添加自定义序列化逻辑
        System.out.println("Custom serialization logic for MySerializableObject");
    }

    // 自定义反序列化方法
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject(); // 反序列化当前对象的非瞬态和非静态字段
        // 可以添加自定义反序列化逻辑
        System.out.println("Custom deserialization logic for MySerializableObject");
    }
}

注意点:

文心一言回答:

  • 只有实现了Serializable接口的对象才能被序列化。
  • 静态字段不会被序列化,因为序列化的是对象的状态,而静态字段属于类,不属于任何对象实例。
  • 序列化可能会因为类的定义发生变化(如添加、删除或重命名字段)而变得不兼容。为了控制版本兼容性,可以在类定义中添加serialVersionUID字段(看自己测试的第二条看完看第三条,能自己测测更好)。
  • 如果对象中包含了对其他对象的引用,并且这些对象也需要被序列化,那么这些对象也必须实现Serializable接口(或者有一个自定义的序列化逻辑,通过实现java.io.Externalizable接口,我也没试过我也不懂)。
  • 序列化过程中会调用对象的writeObjectreadObject方法(如果它们被重写,这俩方法在Serializable 接口的注释里),以及任何可序列化的父类或超类中的这些方法。这允许对象在序列化或反序列化时执行自定义逻辑。然而,通常情况下,你不需要直接重写这些方法,除非你有特殊的序列化需求。

自己测试的:

  • 注意类型的改变后反序列化会失败,包括基本数据类型转成包装类型(如 int改为Integer)
  • 如果版本不改变添加字段、删除字段和重命名字段,对反序列化没有影响,重命名字段只不过字段为null。
  • 序列化基本数据类型的时候会使用基本数据类型的默认值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值