实现对象的反序列化

时间:2014-07-14 07:30:17

标签: java deserialization

像往常一样,我确定这个问题有很多答案,但是,我不知道要搜索什么来找到它们。

假设您有一群动物,Rat Cat DogFish,并且您想序列化/反序列化这些动物。每个都有自己的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);
    }

写完所有这些后,我无法帮助,但注意我的方法需要多少来自其他方的合作/理解。不能保证使用正确的分隔符。我的意思是,任何序列化动物必须有一种方法来识别它是哪种动物,以便可以访问它的反序列化器。这可以通过实现一个包装器来解决,该包装器在将这些信息写入文件之前直接添加它,并在反序列化之前直接将其删除。


为什么不使用内置的序列化/反序列化?

我希望序列化数据易于阅读并且易于编辑。

0 个答案:

没有答案