java - 通过使用空构造函数扩展可以序列化吗?

标签 java serializable

TLDR:当父类没有空构造函数时,有没有办法强制子类有一个空构造函数?

我需要从序列化数据容器初始化一个不可序列化的类,TravelTimeDataArrayTravelTimeDataArray 无法序列化,因为它未实现 Serialized 接口(interface)、缺少空构造函数,并且使用 Link 类型的非序列化字段。

public class TravelTimeDataArray implements TravelTimeData {
    private final double[] timeSum;
    private final int[] timeCnt;
    private final double[] travelTimes;
    private final Link link; //I'm not serializable

    public TravelTimeDataArray(final Link link, final int numSlots) {
        this.timeSum = new double[numSlots];
        this.timeCnt = new int[numSlots];
        this.travelTimes = new double[numSlots];
        this.link = link;
        resetTravelTimes();
    }

//getters and setters
}

我的第一个想法是将其扩展为可序列化的类。我可以使用其 ID 属性的可序列化字符串并添加空构造函数,而不是使用 Link

public class SerialTravelTimeDataArray extends TravelTimeDataArray implements java.io.Serializable{
    private final String linkId = null;  // I am serializable
    public SerialTravelTimeDataArray(){ } 

    public SerialTravelTimeDataArray(TravelTimeDataArray  ttDA){
      // intialize me using ttDA's data
    } 

   // Methods to serialize the fields.

   // Methods to populate super's fields from the deserialized data containers
   }

由于 super 类没有空构造函数,因此我收到子类空构造函数的错误。当父类没有空构造函数时,有没有办法强制子类有一个空构造函数?

最佳答案

根据The Serializable Interface :

A Serializable class must do the following:

  • Implement the java.io.Serializable interface
  • Identify the fields that should be serializable (Use the serialPersistentFields member to explicitly declare them serializable or use the transient keyword to denote nonserializable fields.)
  • Have access to the no-arg constructor of its first nonserializable superclass

对象的第一个不可序列化父类(super class)的无参数构造函数需要具有访问权限,因为它将在反序列化对象时被调用。否则,将会抛出异常。请注意,序列化对象不会调用其父类(super class)的默认构造函数,并且不会引发异常。

如果不需要扩展类,可以考虑使用如下封装:

public class Foo implements Serializable {

    private final double[] timeSum;
    private final int[] timeCnt;
    private final double[] travelTimes;
    private final String linkId;
    private final transient TravelTimeDataArray ttDA;


    public Foo(TravelTimeDataArray ttDA) {
        this.ttDA = ttDA;
        this.timeSum = ttDA.getTimeSum();
        this.timeCnt = ttDA.getTimeCnt();
        this.travelTimes = ttDA.getTravelTimes();
        this.linkId = ttDA.getLink().getId();
    }

    // Methods
}

如果您不需要在类中访问TravelTimeDataArray,则可以跳过字段transient TravelTimeDataArray ttDA。希望这能有所帮助。

关于java - 通过使用空构造函数扩展可以序列化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38165589/

相关文章:

java - 如何使用 Intent 将具有不可序列化子对象的可序列化对象从一个 Android Activity 发送到另一个 Activity

java - 通过对象实例中包含的变量而不是数组编号来搜索数组?

java - 如何缓存和重放 Supplier<Stream<T>> 的项目

java - 在BOE XI中,使用Java SDK,在调度报告时,是否有办法将一些字符串属性存储到实际实例上?

java - (objectinputstream) ObjectInput.readObject() 给我一个空对象

Java - 通过套接字传输时可序列化图像为黑色

java - 错误告诉我运行类中的方法未定义,即使它是

java - 检查Java中的某些现有对象

java - 序列化对象的文件扩展名

database - 可恢复与不可恢复计划