forEach调用时报LinkedHashMap无法强转AttributeDTO的ClassCastException异常
问题根因
从异常堆栈可以直接定位问题:抛出的是ClassCastException,提示LinkedHashMap无法强转为AttributeDTO,和你写的lambda遍历、普通循环逻辑本身没有关系。
问题本质是exportRequestDTO.getAttributeDTOListToInclude()返回的列表中,存储的元素根本不是AttributeDTO实例,而是JSON反序列化时默认生成的LinkedHashMap对象。
触发这个问题的典型原因:
ExportRequestDTO中定义attributeDTOListToInclude字段时使用了原始类型List,没有声明List<AttributeDTO>泛型,Spring默认的Jackson反序列化框架在拿不到目标泛型类型时,会把JSON对象解析为LinkedHashMap存入列表。- 如果
ExportRequestDTO是从远程接口调用、缓存读取后手动反序列化得到的,反序列化时没有指定正确的泛型类型,也会因为Java泛型擦除机制,导致列表内元素被解析为LinkedHashMap。
修复方案
1. 根源修复:修正泛型声明
优先检查ExportRequestDTO类的字段定义,确保对应字段使用正确的泛型声明,不要使用原始类型:
// 错误写法:泛型擦除后反序列化会生成LinkedHashMap private List attributeDTOListToInclude; // 正确写法:明确指定泛型类型,Jackson会自动解析为AttributeDTO private List<AttributeDTO> attributeDTOListToInclude;
如果是手动调用Jackson做JSON反序列化,必须通过TypeReference指定泛型类型,不能直接转成原始List:
// 手动反序列化正确示例 ObjectMapper objectMapper = new ObjectMapper(); List<AttributeDTO> attrList = objectMapper.readValue( jsonContent, new TypeReference<List<AttributeDTO>>() {} );
2. 临时兼容方案
如果暂时无法调整上游的反序列化逻辑,可以在遍历逻辑中手动做类型转换,兼容LinkedHashMap的情况:
List<Integer> ids = new ArrayList<>(); ObjectMapper objectMapper = new ObjectMapper(); for (Object item : exportRequestDTO.getAttributeDTOListToInclude()) { AttributeDTO attributeDTO = objectMapper.convertValue(item, AttributeDTO.class); ids.add(attributeDTO.getId()); }
该方案仅作临时兜底,长期还是要修正上游泛型定义,从根源避免类型错误。
补充说明
不管你用lambda表达式遍历还是普通for循环遍历,只要执行到元素强转AttributeDTO的步骤就会抛出类型转换异常,不需要在遍历语法上做无效排查。
内容的提问来源于stack exchange,提问作者Alejandro Pacheco Tejeda
相关产品推荐
相关产品推荐

