【问题标题】:How does `private void readObject(ObjectInputStream stream)` return an object in custom serialization in Java?`private void readObject(ObjectInputStream stream)`如何在Java的自定义序列化中返回一个对象?
【发布时间】:2021-08-23 14:50:09
【问题描述】:

我正在阅读 Java 中的 custom serialization,您在要序列化的类中提供以下两种方法:

private void writeObject(ObjectOutputStream oos)
private void readObject(ObjectInputStream ois)

例如:

public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    private transient Address address;
    private Person person;

    // setters and getters

    private void writeObject(ObjectOutputStream oos) 
      throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(address.getHouseNumber());
    }

    private void readObject(ObjectInputStream ois) 
      throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        Integer houseNumber = (Integer) ois.readObject();
        Address a = new Address();
        a.setHouseNumber(houseNumber);
        this.setAddress(a);
    }
}

当你想反序列化Employee类的序列化对象时如下:

Employee e2 = (Employee) objectInputStream.readObject();

Java 虚拟机将调用类Employee 中定义的readObject(ObjectInputStream ois) 方法,而不是ObjectInputStream 类(source) 的readObject()。但是,前一种方法不返回任何内容 (void),这与后一种方法返回 Object 类型(应该强制转换)不同。

那么,我们还怎么从上面的自定义反序列化过程中得到Employee对象呢?

【问题讨论】:

  • 我想我以前做过这个,iirc 我将ObjectOutputStream 转换为DataOutputStream,然后将各个字段写入流。然后在阅读时,我只需使用DataInputStream 并阅读并填写每个字段。瞧。

标签: java serialization deserialization


【解决方案1】:

你不会因为这个方法而得到任何额外的对象 - readObject 方法不是静态的,要运行它你需要有实例(比如说Employee 类)并且 - 它是你的对象。

看看例子from this tutorial - 你在那里做的实际上是设置this对象的字段

private void readObject(ObjectInputStream aInputStream) throws ClassNotFoundException, IOException 
{       
    firstName = aInputStream.readUTF();
    lastName = aInputStream.readUTF();
    accountNumber = aInputStream.readInt();
    dateOpened = new Date(aInputStream.readLong());
}

【讨论】:

  • 啊,对。如果这是问题所在,则无需创建其他对象。已经为您创建了对象。 readObject 方法只是为刚刚创建的对象填写特定的实例字段。
  • @m.antkowicz @markspace 所以,你提到的对象(this对象)是JVM不使用构造函数创建的,@的readObject(ObjectInputStream ois)方法987654327@ class 是什么设置了那个对象的字段?
  • 我认为这是一个很好的总结。实现上可能会有细微的差别,但我基本上是这么想的。
  • 我不认为该评论是正确的。某些类型的序列化需要一个无参数的构造函数,但是 JVM 的内置序列化可以在不使用任何构造函数的情况下直接创建一个对象。
  • 呃,你是对的,只是我不知道如何阅读......它写得很清楚:Have access to the no-arg constructor of its first nonserializable superclass - 抱歉这个误导,删除评论
猜你喜欢
  • 2020-11-04
  • 1970-01-01
  • 2018-08-25
  • 1970-01-01
  • 2022-01-11
  • 2019-01-29
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
相关资源
最近更新 更多