Gson反序列化含泛型接口的复杂对象时遇实例化报错问题
解决方案
是的,registerTypeHierarchyAdapter是解决这类问题的有效手段,同时也有其他可选方案,具体如下:
方案一:用registerTypeHierarchyAdapter绑定接口与默认实现
直接为每个接口注册层级适配器,明确序列化/反序列化时使用的实现类:
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .registerTypeAdapterFactory(new GsonValueFieldTypeAdapterFactory()) // 处理OrangeSource接口 .registerTypeHierarchyAdapter(OrangeSource.class, new TypeAdapter<OrangeSource>() { @Override public void write(JsonWriter out, OrangeSource value) throws IOException { new Gson().toJson(value, DefaultOrangeSource.class, out); } @Override public OrangeSource read(JsonReader in) throws IOException { return new Gson().fromJson(in, DefaultOrangeSource.class); } }) // 处理BasicOrange接口(如果需要) .registerTypeHierarchyAdapter(BasicOrange.class, new TypeAdapter<BasicOrange>() { @Override public void write(JsonWriter out, BasicOrange value) throws IOException { new Gson().toJson(value, DefaultBasicOrange.class, out); } @Override public BasicOrange read(JsonReader in) throws IOException { return new Gson().fromJson(in, DefaultBasicOrange.class); } }) .create();
方案二:用InstanceCreator快速指定实例类
如果不需要自定义序列化逻辑,仅需指定反序列化时的实例,用InstanceCreator更简洁:
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .registerTypeAdapterFactory(new GsonValueFieldTypeAdapterFactory()) .registerTypeAdapter(OrangeSource.class, (InstanceCreator<OrangeSource>) type -> new DefaultOrangeSource()) .registerTypeAdapter(BasicOrange.class, (InstanceCreator<BasicOrange>) type -> new DefaultBasicOrange()) .create();
方案三:自定义工厂类批量处理所有Default前缀实现类
如果接口和实现类命名规则固定(接口名对应Default+接口名),可以写通用工厂类批量处理:
public class DefaultTypeAdapterFactory implements TypeAdapterFactory { @SuppressWarnings("unchecked") @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { Class<T> type = (Class<T>) typeToken.getRawType(); // 仅处理接口,且存在对应Default实现类的情况 if (type.isInterface()) { try { // 替换成你的实现类所在包路径 Class<? extends T> implClass = (Class<? extends T>) Class.forName("com.your.package.Default" + type.getSimpleName()); TypeAdapter<T> delegate = gson.getAdapter(TypeToken.get(implClass)); return new TypeAdapter<T>() { @Override public void write(JsonWriter out, T value) throws IOException { delegate.write(out, value); } @Override public T read(JsonReader in) throws IOException { return delegate.read(in); } }; } catch (ClassNotFoundException e) { // 无对应实现类则返回null,交由Gson默认逻辑处理 return null; } } return null; } }
注册这个工厂:
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .registerTypeAdapterFactory(new GsonValueFieldTypeAdapterFactory()) .registerTypeAdapterFactory(new DefaultTypeAdapterFactory()) .create();
优化反序列化TypeToken
配置适配器后,反序列化不需要指定实现类的泛型,直接用接口类型即可:
TypeToken<SearchResult<BasicOrange>> typeToken = new TypeToken<SearchResult<BasicOrange>>() {}; SearchResult<BasicOrange> cachedResponse = gson.fromJson(responseJson, typeToken.getType());
内容的提问来源于stack exchange,提问作者S.Dan
相关产品推荐
相关产品推荐

