序列化反序列化源码分析以及Mybatis中的实际运用

本文深入探讨了序列化和反序列化的过程,特别是JAVA中的序列化机制。通过测试代码和时序图,解释了writeObject、writeReplace、readObject以及readResolve方法的作用。同时,文章还详细分析了Mybatis中序列化技术的实际应用和源码细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

什么是序列化,什么是反序列化

序列化

     JAVA序列化

测试代码

测试结果

序列化时序图

源码分析

  反序列化

反序列化时序图

源码分析

  Mybatis中的实际使用  

源码分析


   主要知识点:

  •      writeObject
  •      writeReplace
  •      readObject
  •      readResolve

什么是序列化,什么是反序列化

            序列化就是将对象转为字节码的过程,反序列化则是将字节码转换为对象的过程

序列化

     JAVA序列化

       java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
  java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
  只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。
  通常对象序列化包括如下步骤:

  1.    创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
  2.   通过对象输出流的writeObject()方法写对象。

  对象反序列化的步骤如下:

  1.   创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
  2.   通过对象输入流的readObject()方法读取对象。

    通过测试代码分析序列化执行过程,通过本文可以理解writeObject,writeReplace方法的执行顺序,以及序列化执行的具体过程。

测试代码

public class Author implements Serializable {

  protected int id;
  protected String username;
  protected String password;
  protected String email;
  protected String bio;
  protected Section favouriteSection;

  public Author() {
    this(-1, null, null, null, null, null);
  }

  public Author(Integer id, String username, String password, String email, String bio, Section section) {
    this.id = id;
    this.username = username;
    this.password = password;
    this.email = email;
    this.bio = bio;
    this.favouriteSection = section;
  }

  public Author(int id) {
    this(id, null, null, null, null, null);
  }

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

  public void setUsername(String username) {
    this.username = username;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public void setBio(String bio) {
    this.bio = bio;
  }

  public void setFavouriteSection(Section favouriteSection) {
    this.favouriteSection = favouriteSection;
  }

  public int getId() {
    return id;
  }

  public String getUsername() {
    return username;
  }

  public String getPassword() {
    return password;
  }

  public String getEmail() {
    return email;
  }

  public String getBio() {
    return bio;
  }

  public Section getFavouriteSection() {
    return favouriteSection;
  }


  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    System.out.println("readObject");
    in.defaultReadObject();
  }


  private void writeObject(ObjectOutputStream out) throws  IOException{
    System.out.println("writeObject");
    out.defaultWriteObject();
  }

  Object writeReplace() throws ObjectStreamException{
    System.out.println("writeReplace");
    Author replaced=new Author();
    replaced.setId(123);
    return replaced;
  }

@Test
  public void testSeria() throws  Exception{
    Author author=new Author();
    author.setId(456);
    Serializable result= deserialize(serialize((Serializable)author));
    System.out.println(((Author)result).getId());
  }

 protected byte[] serialize(Serializable value) throws Exception {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(value);
    oos.flush();
    oos.close();
    return bos.toByteArray();
  }

  protected Serializable deserialize(byte[] value) throws Exception {
    ByteArrayInputStream bis = new ByteArrayInputStream(value);
    ObjectInputStream ois = new ObjectInputStream(bis);
    Serializable result = (Serializable) ois.readObject();
    ois.close();
    return result;
  }

测试结果

上面的测试代码我们序列化的是ID是456的Author对象,但是反序列化后的对象确实12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈脩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值