繁体   English   中英

在 Gson 中使用泛型

[英]Using a generic type with Gson

我正在尝试创建一个用于Google Gson的通用类。 我创建了类GsonJsonConverterImplementation<T> 这个类有以下方法:

public T deserialize(String jsonString) {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("MM/dd/yy HH:mm:ss");

    Gson gson = builder.create();
    return gson.fromJson(jsonString, T); // T.class etc. what goes here
}

目标是此方法应该能够与我设置我的 GsonJsonConverterImplementation 使用的任何类型一起使用。 不幸的是, gson.fromJson(jsonString, T)不起作用,使用T.class代替 T 也不起作用。我确信这个问题源于我对 Java 泛型类型缺乏理解。 在 Gson 中使用泛型的正确方法是什么?

编辑
使用克里斯的回答,我认为这应该有效。 不幸的是,clazz 不能以这种方式使用并导致编译器错误。 使用 Gson 处理集合和泛型类型时,我有哪些选择?

public List<T> deserializeList(String jsonString, Class<T> clazz) {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("MM/dd/yy HH:mm:ss");
    Gson gson = builder.create();

    Type listType = new TypeToken<clazz>(){}.getType(); // compiler error

    return gson.fromJson(jsonString, listType);
}

您尝试的最简单的方法是定义要在方法签名本身中返回的类的类型。 您可以通过将'T'实例传递给方法或将要返回的值的Class传递给它。 第二种方法是在您希望生成返回值的情况下更典型。 以下是使用Gson的这种方法的示例:

public <T> T deserialize(String jsonString, Class<T> clazz) {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("MM/dd/yy HH:mm:ss");

    Gson gson = builder.create();
    return gson.fromJson(jsonString, clazz);
}

用法:

MyClass mc = deserialize(jsonString, MyClass.class);

要获得运行时类型List<T>给定类的, T ,就吮吸,因为JDK不认为我们需要它,所以没有支持。 你可以继承ParameterizedType ,但它真的很糟糕。

    Type typeListT = new ParameterizedType()
    {
        public Type[] getActualTypeArguments()
        {
            return new Type[]{clazz};
        }
        public Type getRawType()
        {
            return List.class;
        }
        public Type getOwnerType()
        {
            return null;
        }
        public boolean equals(Object obj)
        {
            // must implement equals per spec. this sucks
        }
        public int hashCode()
        {
            // this blows! Java forgot to specific it!
            // since we override equals, we should override hashCode
            // we have no idea what value should be returned here!
            // note we are co-existing with other ParameterizedType impls
        }
    };

我正在使用这些方法使用GSON读写Object。

public static <T> void saveAnyTypeOfObject(String key, T value){
        Gson gson = new Gson();
        String json = gson.toJson(value);
        SharedPref.save(key, json);
    }
    //Type listType = new TypeToken<YourClass>(){}.getType();
    public static <T> T readAnyTypeOfObject(String key, Type tt) {
        Gson gson = new Gson();
        String json = SharedPref.read(key, "{}");
        T obj = gson.fromJson(json, tt);
        return obj;
    }

读它就像

  TypeToken<YourClassName> typeToken= new TypeToken<YourClassName>() {};
  YourClassName yourClassName = ListSharedPref.readAnyTypeOfObject("keyForSavingClass", typeToken.getType());

并保存它

YourClassName yourClassName = gson.fromJson(objJsonObject.toString(),YourClassName.class);               
ListSharedPref.saveAnyTypeOfObject("keyForSavingClass",yourClassName);

如果你已经序列化了一个像GenericClass<T>这样的通用对象,那么在反序列化时你应该提供一个具有精确类型的包装类,例如:

public class WrapperClass extends GenericClass<Integer>{
// body is not required
}

然后你可以打电话:

GsonInstance.fromJson(string, WrapperClass.class);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM