【问题标题】:GSON 2.2.2 can not serialize the type "? extend someInterface"GSON 2.2.2 无法序列化类型“?扩展 someInterface”
【发布时间】:2014-01-22 14:10:41
【问题描述】:

Gson 2.2.2 无法序列化 Object1 中的字段。

public class Test {

    public static void  main(String[] args){
        Object1 o1 = new Object1();
        List<Interface1> list1 = new ArrayList<Interface1>();
        Interface1 f1 = new InterfaceImp();
        list1.add(f1);
        o1.field = list1;
        System.out.println(new Gson().toJson(o1));
    }
}
interface Interface1{}
class  InterfaceImp implements Interface1{
    public String s = "123";
}
class Object1 {
    public List<? extends Interface1> field ;
}

调试的时候发现TypeAdapterRuntimeTypeWrapper中的方法

private Type getRuntimeTypeIfMoreSpecific(Type type, Object value) {
    if (value != null && (type == Object.class || type instanceof TypeVariable<?> || type instanceof Class<?>)) {
       type = value.getClass();
}
    return type;
}

不返回 value.getClass()。 arg 'type'(? extends Interface1) 使 if 测试变得错误。一个错误?

【问题讨论】:

  • 嗯,what 类型你希望它返回,究竟是什么?您正在使用有界通配符,这意味着您没有类型。你……不能那样做。

标签: java serialization gson


【解决方案1】:

我认为您需要指定您在 List 中使用的泛型类型

查看此链接

https://sites.google.com/site/gson/gson-user-guide#TOC-Collections-Examples

例如,用于序列化列表:

Type type = new TypeToken<List<Interface1>>(){}.getType();
String s = new Gson().toJson(list1, type);

工作代码(已测试)

public static void main(String[] args) {
    Object1 o1 = new Object1();
    List<Interface1> list1 = new ArrayList<Interface1>();
    Interface1 f1 = new InterfaceImp();
    list1.add(f1);
    list1.add(f1);
    o1.field = list1;

    String s = getGsonWithAdapters().toJson(o1);
    System.out.println(s);
}

public static Gson getGsonWithAdapters() {
    GsonBuilder gb = new GsonBuilder();
    gb.serializeNulls();
    gb.registerTypeAdapter(Object1.class, new CustomAdapter());
    return gb.create();
}

public static class CustomAdapter implements JsonSerializer<Object1> {
    @Override
    public JsonElement serialize(Object1 obj, Type type,
            JsonSerializationContext jsc) {
        JsonObject jsonObject = new JsonObject();
        Type t = new TypeToken<List<Interface1>>() {}.getType();
        jsonObject.add("field", new Gson().toJsonTree(obj.field, t));
        return jsonObject;
    }
}

【讨论】:

  • 我已经通过使用自定义适配器解决了这个问题,但是为什么不让方法'getRuntimeTypeIfMoreSpecific'在这种情况下返回真正的类型呢?
  • 其实我不知道,我也有类似的问题,我也用自定义适配器解决了这个问题,它总是有效,但它需要手动添加一些代码行......无论如何希望我的回答有帮助;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
相关资源
最近更新 更多