AutoValue Gson 不会为数组生成 Gson 类型适配器(至少从我从其源代码中看到的)。因此 Gson 需要一个 List 实例。请注意,您的列表数据模型与 Gson 默认值以及 AutoValue Gson 生成的内容冲突。你有两个解决方案。
解决方案1:不要使用PojoItemList
为什么:数组/列表不需要像itemsList()
. 我不确定您是否会在PojoItemList
except中获得任何其他自动生成的值itemList()
。List<PojoItem>
真的足以让它发挥作用。因此,一个可有效处理列表的原始 Gson 代码:
final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(AutoValueGsonFactory.create())
.create();
final TypeToken<List<PojoItem>> pojoItemListTypeToken = new TypeToken<List<PojoItem>>() {
};
out.println(gson.<List<PojoItem>>fromJson(JSON, pojoItemListTypeToken.getType()));
据我了解,Retrofit 会将类型传递给 Gson 本身,因此,您的 Retrofitted 服务不得PojoItemList
在这种情况下使用,并使用List<PojoItem>
:
interface IService {
List<PojoItem> getPojoItems();
}
请注意,您必须添加一个PojoItem
可以由 AutoValue Gson 生成的类型适配器:
@AutoValue
public abstract class PojoItem {
...
public static TypeAdapter<PojoItem> typeAdapter(final Gson gson) {
return new AutoValue_PojoItem.GsonTypeAdapter(gson);
}
}
如果没有生成并注册类型适配器,Gson 将无法创建PojoItem
实例:
java.lang.RuntimeException:无法调用没有参数的公共 q42240399.PojoItem()
解决方案 2:自己做 AutoValue Gson 工作
如果出于某种原因你想使用PojoItemList
,那么你必须编写你的自定义TypeAdapter
,因为正如我上面提到的,AutoValue Gson 不会生成数组类型适配器(beginArray
虽然我看不到任何调用)。
@AutoValue
public abstract class PojoItemList {
public abstract List<PojoItem> itemList();
public static TypeAdapter<PojoItemList> typeAdapter(final Gson gson) {
// Get the original PojoItem type adapter you can use below
final TypeAdapter<PojoItem> pojoItemTypeAdapter = gson.getAdapter(PojoItem.class);
return new TypeAdapter<PojoItemList>() {
@Override
public void write(final JsonWriter out, final PojoItemList pojoItemList) {
out.beginArray();
for ( final PojoItem pojoItem : pojoItemList.itemList() ) {
pojoItemTypeAdapter.write(out, pojoItem);
}
out.endArray();
}
@Override
public PojoItemList read(final JsonReader in)
throws IOException {
final List<PojoItem> pojoItems = new ArrayList<>();
// The first token must be [
in.beginArray();
// And read until ] is found
while ( in.peek() != END_ARRAY ) {
// Delegate parsing to the PojoItem type adapter for each array element
pojoItems.add(pojoItemTypeAdapter.read(in));
}
// The last token must be ]
in.endArray();
// Construct the PojoItemList value
return new AutoValue_PojoItemList(pojoItems);
}
};
}
}
您可能想询问 AutoValue Gson 扩展作者以实现符合数组的扩展。但是,我认为解决方案#1 更好,原因有几个。
两种解决方案都有效并将产生:
[PojoItem{field1=10, id=0, field2=22}, PojoItem{field1=11, id=1, field2=23}]
PojoItemList{itemList=[PojoItem{field1=10, id=0, field2=22}, PojoItem{field1=11, id=1, field2=23}]}