Java 是否可以通过使用空构造函数扩展来序列化?
TLDR:当超级类没有空构造函数时,有没有办法强制子类拥有空构造函数 我需要从序列化的数据容器中初始化一个不可序列化的类,Java 是否可以通过使用空构造函数扩展来序列化?,java,serializable,Java,Serializable,TLDR:当超级类没有空构造函数时,有没有办法强制子类拥有空构造函数 我需要从序列化的数据容器中初始化一个不可序列化的类,TravelTimeDataArray。无法序列化TravelTimeDataArray,因为它未实现可序列化接口,缺少空构造函数,并且使用类型为Link的不可序列化字段 public class TravelTimeDataArray implements TravelTimeData { private final double[] timeSum; pr
TravelTimeDataArray
。无法序列化TravelTimeDataArray
,因为它未实现可序列化接口,缺少空构造函数,并且使用类型为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属性的可序列化字符串并添加空构造函数,而不是使用链接
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没有空构造函数,因此子类的空构造函数出现错误。当super没有空构造函数时,有没有办法强制子类拥有空构造函数?根据:
可序列化类必须执行以下操作:
- 实现java.io.Serializable接口
- 标识应可序列化的字段(使用serialPersistentFields成员显式声明它们可序列化)
或者使用transient关键字表示不可序列化的字段。)
- 可以访问其第一个非序列化超类的无参数构造函数
对象的第一个非序列化超类的无参数构造函数需要具有访问权限,因为它将在反序列化对象时被调用。否则,将引发异常。请注意,序列化对象不会调用其超类的默认构造函数,也不会引发异常
如果扩展类不是必须的,可以考虑使用如下的封装:
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
字段。希望这能有所帮助。在可序列化类中不需要空构造函数。我知道。我希望我们能以某种方式覆盖super的默认构造函数,使用子类的空构造函数,从而使子类可序列化。这没有意义。默认生成的构造函数将使用基类的默认构造函数;在反序列化期间,没有人会调用可序列化类的默认构造函数;基类没有默认的构造函数,这是实际的问题。你需要退一步思考。是的,这就是我一直采取的方法。我希望有一些Java黑魔法可以绕过“第一个非序列化超类的无参数构造函数”的要求。毕竟,我们可以使用反射来公开私有类。