像往常一样,我确定这个问题有很多答案,但是,我不知道要搜索什么来找到它们。
假设您有一群动物,Rat
Cat
Dog
和Fish
,并且您想序列化/反序列化这些动物。每个都有自己的serialize()
方法。这一切都运行良好,如果你想将你的Cat保存到文件,你可以调用Cat.serialize()
,然后将它写入文件。
但是反序列化呢?当然,您可以保存一些额外的数据来说明动物的类型,然后使用反射来获取静态方法(比如deserialize(String serialized)
),然后调用它。但那不安全。如果有人创造了一种新的动物,兔子会怎么样?并且不包含deserialize(String serialized)
方法?当然,你可以抓住错误并忽略这个问题,但这似乎是不洁净和不好的做法。
您还可以创建枚举。枚举中的每个项必须具有deserialize(String serialized)
方法,并且上述类型的数据表明该类型引用其枚举项的名称。很干净。问题是,不是很适应。 Enums不允许在运行时添加其他动物。
我解决此问题的方法是将对象的名称映射到反序列化器对象。基本上每只动物都必须注册'通过将其名称和反序列化器(实现Deserializer
接口)对象输入HashMap来实现。然后可以在以后通过动物的名称检索反序列化器对象。
我的问题是,实现反序列化的最佳方法是什么?另外,我一直在使用好/坏做法吗?
最后,如果您想知道为什么会在运行时添加动物,原因是动物可能会被程序中其他不可访问的部分或插件等添加。
我一直在使用的方法示例如下。
动物界面
public class Animal{
public String serialize();
}
解串器接口
public interface Deserializer{
public Animal deserialize();
}
Deserializer Storer:
public class AnimalSpecies{
public static final String DELIMITER="|";
private static HashMap<String,GameModeType> species=new HashMap<String,GameModeType>();
public static addSpecies(String speciesName,Deserializer deserializer){
if (species.contains(speciesName)){
//Throw error
}
species.put(speciesName,deserializer);
}
public static Deserializer getSpeciesDeserializer(String speciesName){
return species.get(speciesName);
}
}
Cat class
public class Cat implements Animal{
public static final String DELIMITER=AnimalSpecies.DELIMITER;
private String type;
private int age;
private String name;
public static register(){
AnimalSpecies.addSpecies("CAT",new deserializer());
}
public Cat(String name,String type,Int age){
this.type=type;
this.age=age;
this.name=name;
}
public String serialize(){
return "CAT"+DELIMITER+type+DELIMITER+age+DELIMITER+name;
}
private static class deserializer implements Deserializer{
@Override
public Cat deserialize(String serialized){
String[] split=serialized.split(DELIMITER);
return new Cat(split[3].split[1],Integer.parseInt(split[2]));
}
}
}
然后在你的主要方法中你会打电话:
Cat.register();
当你需要反序列化时:
Deserializer d=AnimalSpecies.getSpeciesDeserializer(serialized.split(AnimalSpecies.DELIMITER)[0]);
if (d!=null){
d.deserialize(serialized);
}
写完所有这些后,我无法帮助,但注意我的方法需要多少来自其他方的合作/理解。不能保证使用正确的分隔符。我的意思是,任何序列化动物必须有一种方法来识别它是哪种动物,以便可以访问它的反序列化器。这可以通过实现一个包装器来解决,该包装器在将这些信息写入文件之前直接添加它,并在反序列化之前直接将其删除。
为什么不使用内置的序列化/反序列化?
我希望序列化数据易于阅读并且易于编辑。