如何让 Gson 反序列化接口类型?

AFH*_*AFH 4 java json gson

我有一个界面

public interace ABC {
}
Run Code Online (Sandbox Code Playgroud)

其实现如下:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public class UVW {
    ABC abcObject;
}
Run Code Online (Sandbox Code Playgroud)

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

是不是因为 UVW 类中使用的接口?如果是,我如何反序列化这样的类?

dur*_*597 5

您需要告诉 GsonXYZ在反序列化时使用ABC您可以使用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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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());
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)