Gson自定义List反序列化器未生效,如何直接返回List<Room>?
解决方案:Retrofit+Gson直接返回List
可以实现直接返回List<Room>,问题出在泛型擦除导致自定义反序列化器未被Gson正确匹配,以下是具体操作步骤:
1. 正确实现RoomListDeserializer
确保反序列化器能从服务器返回的根对象中提取rooms数组并转换为List<Room>:
public class RoomListDeserializer implements JsonDeserializer<List<Room>> { @Override public List<Room> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // 解析根对象中的"rooms"数组 JsonArray roomsJsonArray = json.getAsJsonObject().getAsJsonArray("rooms"); List<Room> roomList = new ArrayList<>(); // 逐个反序列化Room对象 for (JsonElement element : roomsJsonArray) { roomList.add(context.deserialize(element, Room.class)); } return roomList; } }
2. 用TypeToken注册反序列化器
由于Java泛型擦除,直接注册List.class无法让Gson识别List<Room>类型,必须通过TypeToken获取参数化类型来注册:
Gson customGson = new GsonBuilder() .registerTypeAdapter(new TypeToken<List<Room>>() {}.getType(), new RoomListDeserializer()) .create();
3. 配置Retrofit使用自定义Gson
将上述Gson实例传入Retrofit的Gson转换器:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的接口基础URL") .addConverterFactory(GsonConverterFactory.create(customGson)) .build();
4. 定义接口方法
直接返回Call<List<Room>>(或Call<Response<List<Room>>>以获取响应状态码等元数据):
public interface RoomService { @GET("你的接口路径") Call<List<Room>> getRooms(); }
问题根源说明
之前反序列化器未被调用,是因为泛型擦除后Gson无法区分List<Room>与其他List子类,默认尝试将服务器返回的根对象(BEGIN_OBJECT)直接转换为数组类型(BEGIN_ARRAY),从而抛出IllegalStateException。通过TypeToken注册参数化类型的反序列化器,能让Gson精准匹配List<Room>类型,触发自定义解析逻辑。
内容的提问来源于stack exchange,提问作者Bogdan Huanan
相关产品推荐
相关产品推荐

