You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:31:23