将具体类型的对象反序列化为接口类型

时间:2016-02-15 19:18:39

标签: gson

我有一个名为" Clerk"实现了一个名为" Worker"的接口。我想反序列化我的Clerk对象并将其存储到Worker对象中,就像我们通常可以做的那样:

Worker clerkWorker = new Clerk("abc", "alice white");

只有我有职员json,我想反序列化并存储到clerkWorker:

{
  "uid": "1a-2wq"
  "name": "Maryanne Chen"
}

界面:

public interface Worker {
  int getUID();
  String getName();
  void work();
}

实施它的类:

private class Clerk implements Worker {
  int uid;
  String name;

  public Clerk(id, fullname) {
    uid = id;
    name = fullname;
  }

  public void work() {
    System.out.println("Clerk is processing files");
  }
}

按照此处描述的第二个解决方案:Using Gson with Interface Types我在本地复制了RuntimeTypeAdapterFactory以使用它:

RuntimeTypeAdapterFactory typeFactory =     
RuntimeTypeAdapterFactory.of(Worker.class, "type");
typeFactory.registerSubtype(Clerk.class);
Gson gson = new GsonBuilder().registerTypeAdapterFactory(typeFactory).create();

final Reader r = getReader(jsonFile);
return gson.fromJson(r, typeToken.getType());

我已验证我的getReader功能正常运行。我得到一个例外:

"无法反序列化接口Worker,因为它没有定义名为type"的字段。

2 个答案:

答案 0 :(得分:1)

当你告诉Gson用接口类型反序列化某些内容时,它必须以某种方式确定它应该使用哪个实现类。它通过检查json数据中的特殊字段来完成此操作。当你打电话给RuntimeTypeAdapterFactory.of(Worker.class, "type");时,你告诉Gson它应该检查的字段,以确定它应该使用哪个类名为" type"。当你给它一大块没有该字段的json数据时,它会抱怨。

要解决此问题,您需要添加"类型"字段到您的json数据,或告诉Gson在代码中反序列化为Clerk,而不是Worker

答案 1 :(得分:1)

如果Clerk Worker,那么就没有任何理由你不能完全按照你在构造函数示例中展示的那样做。

Worker w = (new Gson()).fromJson( jsonData, Clerk.class ) ;

我不确定为什么你这么想要立刻向上投射,因为任何想要Worker的人都应该能够直接接受Clerk ......