我做了一般类型测试。
class A {}
class B extends A {}
有两种方法:
private static void extendTest(List<? extends A> superList) {
System.out.println("extendTest over.");
}
private static void extendMapTest(HashMap<String, List<? extends A>> superMap) {
System.out.println("extendMapTest over.");
}
我创建了一个list
和一个map
:
List<B> childList = new ArrayList<>();
childList.add(new B());
extendTest(childList); // TAG1: it is OK.
HashMap<String, List<B>> childMap = new HashMap<>();
childMap.put("hello", childList);
extendMapTest(childMap); // TAG2: ERROR!
为什么TAG1没问题,而TAG2错误? 我怎样才能纠正TAG2?
答案 0 :(得分:4)
List<? extends A>
不是List<B>
的超级类型。请参阅the offical generics tutorial on upper bounding。
要修复,请按以下方式定义childList:
List<A> childList = new ArrayList<>();
您仍然可以向B
添加List<A>
,因为a
B
是A
。
并定义你的地图方法:
private static void extendMapTest(HashMap<String, List<A>> superMap) {...
答案 1 :(得分:0)
就像List<Integer>
一样简单,不是List<Number>
的子类型,即使数字和整数是相关的,但AnyClass<A>
与AnyClass<B>
无关,如图所示在docs中也是
简单的选项只是使用外卡定义您的地图,无需更改代码,例如
HashMap<String, List<? extends A>> childMap = new HashMap<>();
例如使用修改后的代码进行演示
class A {}
class B extends A {
public int a=9;
}
private static void extendTest(List<? extends A> superList) {
System.out.println("extendTest over.");
}
private static void extendMapTest(HashMap<String, List<? extends A>> superMap) {
System.out.println("extendMapTest over."+((B)(superMap.get("hello").get(0))).a);
}
List<B> childList = new ArrayList<>();
childList.add(new B());
extendTest(childList);
HashMap<String, List<? extends A>> childMap = new HashMap<>();
childMap.put("hello", childList);
extendMapTest(childMap);
输出:
extendTest over.
extendMapTest over.9
答案 2 :(得分:0)
要考虑的一件事。
您可以创建另一个类
class C extends A {}
并在extendMapTest(HashMap<String, List<? extends A>> superMap)
你可以自由地做:
List<C> list = new ArrayList<>();
list.add(new C());
superMap.put("A", list);
但这与您传递给extendMapTest的childMap对象的声明相矛盾
HashMap<String, List<B>> childMap
我猜编译错误会阻止此情况或类似情况