Java中List<Object>无法兼容多种泛型列表的问题求助
Java泛型问题:如何让Map接收多种类型的List
为什么会出现编译错误?
Java的泛型是不变的——哪怕BigDecimal是Object的子类,List<BigDecimal>也不是List<Object>的子类。编译器会严格检查泛型类型匹配,所以你不能直接把List<BigDecimal>赋值给List<Object>类型的参数。
解决方案
方案1:使用通配符List<?>
把Map的泛型定义为Map<String, List<?>>,List<?>表示任意类型的List,能接收List<BigDecimal>、List<String>等所有具体类型的List:
public Map<String, List<?>> getFFF(){ Map<String, List<?>> p = new HashMap<>(); List<BigDecimal> x = new ArrayList<>(); // 注意:用字符串构造BigDecimal避免double精度丢失 x.add(new BigDecimal("0.43443434344")); x.add(new BigDecimal("0.43443434343")); p.put("FFF", x); // 编译通过 // 可以添加其他类型的List List<String> strList = new ArrayList<>(); strList.add("hello"); p.put("STRING_LIST", strList); List<Long> longList = new ArrayList<>(); longList.add(123L); p.put("LONG_LIST", longList); return p; }
注意:List<?>是只读的(除了能添加null),因为编译器不知道它实际存储的是什么类型,所以无法安全添加元素。但如果你只是把已初始化好的List存入Map,这个方案完全适用。
方案2:使用List<Object>统一存储
如果之后需要往Map中的List添加元素,可以把所有List声明为List<Object>,直接存放各种类型的对象:
public Map<String, List<Object>> getFFF(){ Map<String, List<Object>> p = new HashMap<>(); List<Object> x = new ArrayList<>(); x.add(new BigDecimal("0.43443434344")); x.add(new BigDecimal("0.43443434343")); p.put("FFF", x); List<Object> strList = new ArrayList<>(); strList.add("test"); p.put("STR_LIST", strList); // 后续还能往List里加任意类型元素 x.add(123L); return p; }
这个方案的缺点是,从List中取元素时需要强制转换类型(比如(BigDecimal) x.get(0)),容易出现ClassCastException,需要额外的类型检查。
你的疑问解答
不存在一种泛型List可以同时完美接收所有类型的List,并且保留原类型的全部操作便利性。但可以通过两种方式实现需求:
- 用
List<?>接收任意类型的List,适合只读取List元素的场景; - 用
List<Object>存储各种类型的对象,适合需要修改List元素的场景。
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

