简体   繁体   English

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

[英]Serializable by extending with empty constructor?

TLDR: Is there a way to force to a subclass to have an empty constructor when the super does not? TLDR:有没有一种方法可以在超类没有时强制子类具有空的构造函数?

I need to be to initialize a non-serializable class, TravelTimeDataArray , from a serialized data container. 我需要从序列化的数据容器初始化一个不可序列化的类TravelTimeDataArray The TravelTimeDataArray cannot be serialized because it does not implement the Serializable interface, lacks an empty constructor, and uses a non-serializable field of type Link . TravelTimeDataArray无法序列化,因为它没有实现Serializable接口,缺少空的构造函数,并且使用Link类型的non-serializable字段。

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
}

My first thought was to extend this as a serializable class. 我的第一个想法是将其扩展为可序列化的类。 Instead of using a Link , I can use a serializable String of it's ID attribute and add the empty constructor. 除了使用Link ,我还可以使用ID属性的可序列化的String并添加空的构造函数。

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
   }

Since the super does not have an empty constructor, I get an error with the subclass's empty constructor. 由于父类没有空的构造函数,因此子类的空的构造函数出现错误。 Is there a way to force to a subclass to have an empty constructor when the super does not? 当超级类没有时,是否有一种方法可以强制子类具有空的构造函数?

According to The Serializable Interface : 根据可序列化接口

A Serializable class must do the following: Serializable类必须执行以下操作:

  • Implement the java.io.Serializable interface 实现java.io.Serializable接口
  • 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.) 标识应可序列化的字段(使用serialPersistentFields成员显式声明它们可序列化,或使用transient关键字表示不可序列化的字段。)
  • Have access to the no-arg constructor of its first nonserializable superclass 可以访问其第一个不可序列化超类的no-arg构造函数

A no-arg constructor of a object's first nonserializable superclass is need to have access because it will be called while deserializing the object. 需要访问对象的第一个不可序列化超类的无参数构造函数,因为在反序列化对象时将调用它。 Otherwise, an exception will be thrown. 否则,将引发异常。 Note that serializing a object do not call its superclass's default constructor and no exception will be thrown. 请注意,序列化对象不会调用其超类的默认构造函数,并且不会引发任何异常。

If extending a class is not a must, you can consider using encapsulation like follows: 如果扩展类不是必须的,则可以考虑使用如下封装:

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
}

If you do not need to access TravelTimeDataArray in your class, you can skip the field transient TravelTimeDataArray ttDA . 如果不需要在您的类中访问TravelTimeDataArray ,则可以跳过transient TravelTimeDataArray ttDA字段。 Hope this can help. 希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM