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

Java 17中使用ModelMapper出现类型不匹配的困惑

问题解析:Java泛型擦除导致的类型安全异常场景

问题描述

使用Java 17搭配ModelMapper时出现违背直觉的类型行为:将List<Test>类型的转换结果添加到ArrayList<Boolean>中,代码不仅能编译通过,还能正常执行并输出混合了Test对象和Boolean值的列表。

代码复现

import java.util.ArrayList;
import java.util.List;
import org.modelmapper.ModelMapper;
import com.google.gson.reflect.TypeToken;

public final class ModelMapperAdapter {

    private static ModelMapper MODEL_MAPPER;

    public static class Test{
        Integer var;
        // getter、setter省略
    }
    
    public static void main(String[] args) {
        MODEL_MAPPER = new ModelMapper();
        Test test = new Test();
        List<Test> list = new ArrayList<>();
        List<Boolean> ids = new ArrayList<>();
        list.add(test);
        ids.addAll(MODEL_MAPPER.map(list, new TypeToken<List<Test>>(){}.getType()));
        System.out.println(ids);// [ModelMapperAdapter.Test(var=null)]
        ids.add(true);
        System.out.println(ids);// [ModelMapperAdapter.Test(var=null), true]     
    }
}

核心原因:Java泛型的类型擦除机制

  • 编译时检查,运行时擦除:Java泛型是编译期特性,编译后所有泛型类型信息会被擦除,List<Boolean>和List<Test>在运行时都会被视为原始类型List。
  • 未经检查的类型转换:ModelMapper.map()方法返回的是Object类型,调用addAll()时,编译器仅做形式上的类型兼容校验,不会验证传入集合的实际元素类型是否与目标列表泛型匹配,直接放行未经检查的类型转换。
  • 运行时的原始类型兼容:因为List在运行时是原始类型,本质上存储的是Object对象,所以添加Test实例和Boolean值都不会触发类型转换异常,只有当你尝试将列表元素强制转换为Boolean时,才会抛出ClassCastException。

解决方案

  • 显式指定类型转换逻辑:先获取正确类型的转换结果,再手动实现Test到Boolean的映射,让编译器做严格类型检查:
    List<Test> mappedList = MODEL_MAPPER.map(list, new TypeToken<List<Test>>(){}.getType());
    // 根据业务需求实现Test到Boolean的转换逻辑,示例:判断var是否非空
    List<Boolean> ids = mappedList.stream()
                                  .map(test -> test.getVar() != null)
                                  .collect(Collectors.toList());
    
  • 启用编译警告:编译时添加-Xlint:unchecked参数,让编译器提示未经检查的类型转换操作,提前发现这类潜在风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:16:02