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

为何Jackson反序列化后在stream().findAny()步骤出现类型转换异常?

问题解析:Jackson反序列化泛型工具类的延迟类型转换异常

原类内代码正常运行的原因

在类A中使用new TypeReference<>(){}时,编译器处于具体的上下文里——你实际要反序列化的是List<X>(而非代码表面写的List<Object>),匿名内部类TypeReference会保留这个实际的泛型类型信息(通过反射可获取)。Jackson拿到明确类型后,会把JSON数组里的每个元素直接反序列化为X对象,后续stream过滤、查找操作自然不会有类型问题。

原类代码:

public class A {
    // ...获取需映射为对象的JSON代码...
    String jsonString = response_I_got_via_RESTAssured.getBody();
    ObjectMapper mapper = new ObjectMapper();
    List<Object> myObj = objectMapper.readValue(jsonString, new TypeReference<>(){});
}

工具类错误版本延迟报错的核心原因

错误的泛型方法里,new TypeReference<>(){}是在泛型方法内部创建的。由于Java泛型擦除机制,编译后泛型参数T的具体类型信息会丢失,Jackson无法识别你要反序列化的是List<X>,只能默认把JSON中的每个对象反序列化为LinkedHashMap(Jackson处理未知类型对象的默认实现)。

这里的关键是:泛型方法返回T时,编译器会做一次未经检查的强制类型转换——把List<LinkedHashMap>强制转成你调用时期望的List<X>。由于JVM运行时没有泛型类型信息,这次转换不会立刻抛出异常,代码能正常走到stream操作步骤。

直到你调用findAny()后尝试把结果转换成X类型(比如赋值给X变量、用cast方法转换),JVM才会检查实际对象的类型,发现是LinkedHashMap而非X,这时才抛出LinkedHashMap cannot be cast to X的异常。

错误工具类代码:

public static <T> T method(RestAssured response) {
    String jsonString = response_I_got_via_RESTAssured.getBody();
    ObjectMapper mapper = new ObjectMapper();
    return objectMapper.readValue(jsonString, new TypeReference<>(){});
}

修复方法生效的原因

修复后传入TypeReference参数,相当于把具体的泛型类型信息(比如new TypeReference<List<X>>(){})明确传递给Jackson。Jackson拿到完整类型信息后,会直接把JSON数组反序列化为List<X>,每个元素都是X类型,后续的stream操作、类型转换自然不会有异常。

修复后工具类代码:

public static <T> T method(RestAssured response, TypeReference reference) {
    String jsonString = response_I_got_via_RESTAssured.getBody();
    ObjectMapper mapper = new ObjectMapper();
    return objectMapper.readValue(jsonString, reference);
}

内容的提问来源于stack exchange,提问作者Maria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:33:15