Java中无法将泛型List添加到泛型Map?求修改兼容方案
解决泛型Map添加不同类型列表的问题
这个问题的核心是Java泛型的不变性导致的——虽然A<Integer>是A<?>的子类,但作为容器的List是泛型不变的,也就是说List<A<Integer>>并不是List<A<?>>的子类型,直接往Map<String, List<A<?>>>里放自然会报错。下面给你两种可行的解决方案:
方案一:使用协变通配符(推荐,适合只读场景)
如果你只需要从Map中读取列表、不需要往列表里添加元素,把Map的value类型改成List<? extends A<?>>就可以了:
Map<String, List<? extends A<?>>> map = new HashMap<>(); List<A<Integer>> list1 = getData(); List<A<String>> list2 = getData2(); map.put("a", list1); map.put("b", list2); // 现在可以正常运行了
这里的? extends A<?>表示“任何继承自A<?>的类型的列表”,利用泛型的协变特性,让List<A<Integer>>和List<A<String>>都能被接受。
方案二:强制类型转换(适合需要写入元素的场景)
如果之后需要往Map中的列表添加元素,上面的协变通配符就不太方便了(因为List<? extends A<?>>不能添加除null以外的元素)。这时候可以保留Map<String, List<A<?>>>的定义,在put时做一次unchecked类型转换:
Map<String, List<A<?>>> map = new HashMap<>(); List<A<Integer>> list1 = getData(); List<A<String>> list2 = getData2(); // 先转成List<?>再转成List<A<?>>,避免编译错误 @SuppressWarnings("unchecked") List<A<?>> convertedList1 = (List<A<?>>) (List<?>) list1; map.put("a", convertedList1); @SuppressWarnings("unchecked") List<A<?>> convertedList2 = (List<A<?>>) (List<?>) list2; map.put("b", convertedList2);
这里的@SuppressWarnings("unchecked")是用来消除编译器的unchecked警告的,因为我们明确知道这个转换是安全的。
另外你提到的Map<String, List<A>>不行,是因为List<A<Integer>>同样不是List<A>(raw type)的子类型,而且使用raw type会丢失泛型的类型安全,不推荐这么做。
内容的提问来源于stack exchange,提问作者CCC
相关产品推荐
相关产品推荐

