【问题标题】:How can I get Gson to deserialize an interface type? [duplicate]如何让 Gson 反序列化接口类型? [复制]
【发布时间】:2015-11-04 06:28:01
【问题描述】:

我有一个界面

public interace ABC {
}

这个的实现如下:

public class XYZ implements ABC {
    private Map<String, String> mapValue;
    public void setMapValue( Map<String, String> mapValue) {
        this.mapValue = mapValue;
    }  

    public  Map<String, String> getMapValue() {
        return this.mapValue
    }
}

我想反序列化一个使用 Gson 实现的类

public class UVW {
    ABC abcObject;
}

当我尝试像 gson.fromJson(jsonString, UVW.class); 那样反序列化它时,它返回给我 null。 jsonString 是 UTF_8 字符串。

是因为UVW类中使用的接口吗?如果是,我该如何反序列化此类?

【问题讨论】:

  • 只给ABC类型的字段,Gson怎么知道如何反序列化JSON?
  • 如何让 Gson 知道使用 ABC 的实现 XYZ?
  • 我不相信 Gson 有这样的内置功能(多态反序列化)。您需要编写一个自定义反序列化器,从 JSON 中获取某种提示以了解如何反序列化它。看看杰克逊。它内置了这个功能。
  • @SotiriosDelimanolis 这个问题已经过时了。他建议使用RuntimeTypeAdapterFactory,现在在代码库中(他说不是),然后建议使用JsonDeserializer,现在基本上已弃用。
  • 如果您愿意,可以提供更新的答案。无需跨问题传播。

标签: java json gson


【解决方案1】:

您需要告诉 Gson 在反序列化 ABC 时使用 XYZYou can do this using a TypeAdapterFactory.

简而言之:

public class ABCAdapterFactory implements TypeAdapterFactory {
  private final Class<? extends ABC> implementationClass;

  public ABCAdapterFactory(Class<? extends ABC> implementationClass) {
     this.implementationClass = implementationClass;
  }

  @SuppressWarnings("unchecked")
  @Override
  public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    if (!ABC.class.equals(type.getRawType())) return null;

    return (TypeAdapter<T>) gson.getAdapter(implementationClass);
  }
}

这是一个完整的工作测试工具,用于说明此示例:

public class TypeAdapterFactoryExample {
  public static interface ABC {

  }

  public static class XYZ implements ABC {
    public String test = "hello";
  }

  public static class Foo {
    ABC something;
  }

  public static void main(String... args) {
    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapterFactory(new ABCAdapterFactory(XYZ.class));
    Gson g = builder.create();

    Foo foo = new Foo();
    foo.something = new XYZ();

    String json = g.toJson(foo);
    System.out.println(json);
    Foo f = g.fromJson(json, Foo.class);
    System.out.println(f.something.getClass());
  }
}

输出:

{"something":{"test":"hello"}}
class gson.TypeAdapterFactoryExample$XYZ

【讨论】:

  • 如果您只有一个子类型,这很简单。在这种情况下,您不需要为目标类型添加任何提示。添加另一个子类型,它变得更加复杂。
  • 如果我有 XYZ 类,我该如何实现?
猜你喜欢
  • 1970-01-01
  • 2010-12-08
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多