可以通过使用空构造函数扩展来序列化吗?
Serializable by extending with empty constructor?
TLDR:有没有办法强制 subclass 有一个空的构造函数,而 super 没有?
我需要从序列化的数据容器中初始化不可序列化的 class、TravelTimeDataArray
。 TravelTimeDataArray
无法序列化,因为它没有实现 Serializable 接口,缺少空构造函数,并且使用了 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
}
我的第一个想法是将其扩展为可序列化 class。我可以使用它的 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 没有空构造函数,我在 subclass 的空构造函数中遇到错误。有没有办法在 super 没有时强制 subclass 有一个空的构造函数?
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
对象的第一个不可序列化的超类class 的无参数构造函数需要具有访问权限,因为它将在反序列化对象时调用。否则,将抛出异常。请注意,序列化一个对象不要调用它的 superclass 的默认构造函数,并且不会抛出异常。
如果扩展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
}
如果您不需要在 class 中访问 TravelTimeDataArray
,您可以跳过字段 transient TravelTimeDataArray ttDA
。希望这可以帮助。
TLDR:有没有办法强制 subclass 有一个空的构造函数,而 super 没有?
我需要从序列化的数据容器中初始化不可序列化的 class、TravelTimeDataArray
。 TravelTimeDataArray
无法序列化,因为它没有实现 Serializable 接口,缺少空构造函数,并且使用了 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
}
我的第一个想法是将其扩展为可序列化 class。我可以使用它的 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 没有空构造函数,我在 subclass 的空构造函数中遇到错误。有没有办法在 super 没有时强制 subclass 有一个空的构造函数?
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
对象的第一个不可序列化的超类class 的无参数构造函数需要具有访问权限,因为它将在反序列化对象时调用。否则,将抛出异常。请注意,序列化一个对象不要调用它的 superclass 的默认构造函数,并且不会抛出异常。
如果扩展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
}
如果您不需要在 class 中访问 TravelTimeDataArray
,您可以跳过字段 transient TravelTimeDataArray ttDA
。希望这可以帮助。