Serializable序列化工作原理/代码实现

本文探讨了Java序列化的工作原理,包括Serializable接口的特点、ObjectOutputStream的使用,以及HashMap和ArrayList在序列化时的处理。提供了序列化和反序列化的代码实例,并指出transient和静态成员变量的行为。通过序列化,可以理解如何处理对象状态的保存和恢复,以及在单例模式中的应用。
摘要由CSDN通过智能技术生成

通常我们使用Java的序列化与反序列化时,只需要将类实现Serializable接口即可,剩下的事情就交给了jdk。今天我们就来探究一下,Java序列化是怎么实现的,然后探讨一下几个常见的集合类,他们是如何处理序列化带来的问题的。

Serializable

先看Serializable接口,源码很简单,一个空的接口,没有方法也没有成员变量。但是注释非常详细,很清楚的描述了Serializable怎么用、能做什么,很值得一看,我们捡几个重点的翻译一下,

/**
 * Serializability of a class is enabled by the class implementing the
 * java.io.Serializable interface. Classes that do not implement this
 * interface will not have any of their state serialized or
 * deserialized.  All subtypes of a serializable class are themselves
 * serializable.  The serialization interface has no methods or fields
 * and serves only to identify the semantics of being serializable. 
 */
复制代码

类的可序列化性通过实现java.io.Serializable接口开启。未实现序列化接口的类不能序列化,所有实现了序列化的子类都可以被序列化。Serializable接口没有方法和属性,只是一个识别类可被序列化的标志。

/**
 * Classes that require special handling during the serialization and
 * deserialization process must implement special methods with these exact
 * signatures:
 *
 * <PRE>
 * private void writeObject(java.io.ObjectOutputStream out)
 *     throws IOException
 * private void readObject(java.io.ObjectInputStream in)
 *     throws IOException, ClassNotFoundException;
 * private void readObjectNoData()
 *     throws ObjectStreamException;
 * </PRE>
 */
复制代码

在序列化过程中,如果类想要做一些特殊处理,可以通过实现以下方法writeObject(), readObject(), readObjectNoData(),其中,

  • writeObject方法负责为其特定类写入对象的状态,以便相应的readObject()方法可以还原它。
  • readObject()方法负责从流中读取并恢复类字段。
  • 如果某个超类不支持序列化,但又不希望使用默认值怎么办?writeReplace() 方法可以使对象被写入流之前,用一个对象来替换自己。
  • readResolve()通常在单例模式中使用,对象从流中被读出时,可以用一个对象替换另一个对象。

Serializable接口特点

  • 序列化类的属性没有实现 Serializable 那么在序列化就会报错
public class User {
    private String name;
    private int age;
    public static void main(String[] args) throws IOException {
        try (ObjectOutputStream outputStream =
                new ObjectOutputStream(new FileOutputStream("User.txt"))) {
            User user = new User();
            user.name = "zouwei";
            user.age = 22;
            outputStream.writeObject(user);
            outputStream.flush();
        }
    }
}
复制代码

编辑切换为居中

添加图片注释,不超过 140 字(可选)

  • 在序列化反序列化过程中,父类没有实现序列化接口,那么父类的属性将不会参与到序列化反序列化的过程中,父类需要提供无参构造函数来重新创建对象
public class Animal {
    private int age;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
public class Dog extends Animal implements Serializable {
    private static final long serialVersionUID = -8559877565455401808L;
    private String name;
    public static void main(String[] args) throws Exception {
        // 序列化
        serialObject();
        // 反序列化
        deserialObject();
    }
    private static void serialObject() throws IOException {
        try (ObjectOutputStream outputStream =
                new ObjectOutputStream(new FileOutputStream("Dog.txt"))) {
            Dog dog = new Dog();
            dog.name = "Black";
            dog
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值