【问题标题】:How to deserialize different subtypes with generics with one gson deserializer如何使用一个 gson 反序列化器反序列化具有泛型的不同子类型
【发布时间】:2017-02-03 09:38:47
【问题描述】:

我必须为不同的测试用例保存配置对象。我决定为此使用 GSON,因为我已经使用过。问题是配置文件的结构/继承在其定义中包含泛型。如果这是重复的,我已经阅读了该主题,但无法将其应用于我的问题。代码被分解到最少。

配置类

除了其他易于序列化的组件之外,它还有一个ArrayList<T>

//There are classes that inherit from that too
public class Configuration<T extends ParamSet> implements Iterable<T>{

    // this list is what i want to set from my ApplicationClass
    private ArrayList<T> _paramSets = new ArrayList<T>();

    //getter, setter and constructor
}

ParameterSet 定义

这些课程没有什么特别之处。只是整数和布尔值。

public class ParamSet {}

public class ChildParamSet extends ParamSet{}

抽象应用类

这是保存过程的开始。我定义了一个抽象方法,稍后在运行时已知T 的类中实现。

public abstract class ApplicationClass<T extends ParamSet>{

    private Configuration<T> config;

    // in this method i want to set either a new config or new params in the config
    public setupConfig(){
        //some checks and if the user wants to load a config from file
        loadConfig(file);       
    }
    //abstract method to be called in more concrete classes
    abstract protected Configuration<T> loadConfig(File file);
}

具体应用类

我知道T 的类型,我想调用getConfiguration方法。

public abstract class MoreConcreteApplicationClass extends ApplicationClass<ChildParamSet>{

    //constructor and other stuff

    @Override
    protected Configuration<ChildParamSet> loadConfig(File file){
        return ConfigurationPersistenceHelper.getConfiguration(file);
    }   
}

Configuration Persistence Helper -- 问题

public class ConfigurationPersistenceHelper(){

    //i get the configuration with a linked treeMap --> wrong type 
    public static <T extends ParamSet> Configuration<T> getConfiguration(final File location){
        GsonBuilder builder = new GsonBuilder();
        GsonBuilder builder.enableComplexMapKeySerialization.create();

        final Type type = new TypeToken<Configuration<T>>(){}.getType();

        final String jsonRepresentation =  new String(Files.readAllBytes(location.toPath()));
        return gson.fromJson(jsonRepresentation, type);

    }
}

所以问题出在 ConfigurationPersistenceHelper 中的getConfiguration 方法上。当我运行此方法时,我在配置中得到了 Linked TreeMap 而不是 ArrayList&lt;ChildParamSet&gt;

我猜这是因为泛型在运行时的类型擦除以及我使用T extends ParamSet 定义的方法。

但是我该如何解决这个问题?是否有另一种方法来调用该方法以使类型不会丢失?

我知道的解决方法

我知道我可以在每个具体应用程序类的loadConfig 方法中实现反序列化器逻辑。但这会导致很多重复的代码。这是我目前的解决方案。

我还知道我可以将类型从loadConfig(该类型在运行时仍然可用)传递给getConfiguration 方法。这是不好的做法吗?

我也知道我可以编写自己的反序列化器,但在运行时我还需要该类型,这是我目前的问题。

【问题讨论】:

    标签: java generics inheritance gson type-erasure


    【解决方案1】:

    是的,类型擦除是问题所在。只需像这样传递类型信息:

    abstract protected Configuration<T> loadConfig(File file, Class<T> clazz);
    

    在该方法中为您的 ArrayList 使用自定义 ParameterizedType,请参阅:

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    相关资源
    最近更新 更多