为何Jackson反序列化后在stream().findAny()步骤出现类型转换异常?
原类内代码正常运行的原因
在类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

