当前位置: 首页 > 知识库问答 >
问题:

如何用一个gson反序列化器反序列化具有泛型的不同子类型

梁丘缪文
2023-03-14
//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
}
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);
    }   
}
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方法。运行此方法时,配置中得到的不是ArrayList 而是链接的TreeMap

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

此外,我知道我可以将类型从LoadConfig(其中类型在运行时仍然可用)传递给GetConfiguration方法到序列化程序。这是不是很糟糕的练习?

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

共有1个答案

贲言
2023-03-14

是的,类型删除是问题所在。只需传入类型信息,如下所示:

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

在该方法内部,请为ArrayList使用自定义ParameterizedType,请参阅:

  • 作为GSON参数的Java类型泛型
  • 在GSON中反序列化泛型列表
 类似资料:
  • 我有一个Api,Api如下所示: 如果响应是ok,那么结构将以关键字开头,例如: 问题是:我如何为父类创建一个反序列化器,它也会反序列化子类(作为我的第二种方法),或者我如何用Gson创建一个泛型类,这样包装在周围的每个tyoe都可以与它一起使用,比如: public class DataObjectDeserializer implements JsonDeserializer{

  • 问题内容: 我正在使用GSON 1.4,并使用两个通用对象序列化对象,如下所示 。当我对它进行反序列化时 可悲的是我得到了 java.lang.IllegalArgumentException:无法将java.util.ArrayList字段…设置为java.util.LinkedList 这是为什么 ?GSON文档指出,如果我使用object.class参数进行序列化,则它支持泛型。任何想法?谢

  • 我在Android应用程序中实现Json反序列化时遇到了一些问题(带有Gson库)

  • 您将获得对象(或对象列表),而不是作为传递的实际对象(或第二种情况下的实际对象列表)。 如果您想要一个仍然想要反序列化泛型类型对象(-s),请参阅下面的答案。 +红利:LoopJ+GSON的最终通用解决方案 如何获取泛型接口的具体类型 Java类型Generic作为GSON的参数

  • 我有一门课是这样的: 但是当我试图序列化它时,我收到一个错误,上面写着“试图序列化java.lang.class:java.lang.字符串。忘记注册一个类型适配器了吗?”。所以我创建了这个适配器: } 并登记如下: 但我还是犯了同样的错误<我做错了什么 适配器的实现看起来正常吗?

  • 问题内容: 我正在尝试使用Gson 反序列化a ,值的类型可以变化,值“ in_wanted”可以是a 或a 。 in_wanted为: in_wanted为: 每当“ in_wanted”的值为布尔值时,我都需要该对象,并且需要一个反序列化器以返回null。用Gson做到这一点的最佳方法是什么? 问题答案: 您可以使用自定义解串器来完成此操作。首先,我们应该创建可以表示您的JSON的数据模型。