这是我很确定已经多次回答的问题,但我找不到答案。我有一个接受 List<Object> ls = new ArrayList<Object>();
for (Foo foo: fooList) {
// Foo setters
}
ls.add( foo);
// Foo class goes like
public class Foo{
private String name;
private String status;
的方法,但是当我尝试为其分配Map<Object, Object>
时,这是不可能的。我出于某种原因甚至无法对地图进行类型转换。
这很奇怪。我的想法是,因为每个班级都是Map<TypeA, TypeB>
,所以任何类型的Object
也应该是Map
。
似乎我对这个问题的理解是不完整的,我在哪里感到困惑?
答案 0 :(得分:3)
这种行为是有原因的。让我们以相反的方式解决它。
让我们假设它有效(稍后我们会看到不良影响,因此会得出结论为什么决定让它不编译)
public class Some{
private Map < Object, Object > map;
public class setMap(Map < Object,Object > map){
this.map = map;//considering it was allowed and implicit casting was done.
this.map.add(1,2);
this.map.add(new Student(), new Object());
this.map.add("abcd", new Student());
this.map.add(new Employee(), new House());
this.map.add(new Whatever(), new EveryThing());
// In short now map can hold any object as key and value without promoting any compile error.
}
public void setStudentNameMap(){
setMap(new HashMap < String, Student >());
// What key value pairs now we expect to be of type while iterating ?
}
}
在上面的代码中,我们希望map能够保存String类型的键,并且值为Student对象的类型,因此我们使用泛型并提供了类型。但它对我们有帮助吗?甚至我们提供的类型仍然是后来的任何类型的对象都可以设置为关键和值,这只是违反了泛型的使用。
想象一下现在在方法setStudentNameMap()
中迭代地图。关键和价值的预期类型是什么?字符串和学生分别为键和值。但是我们得到的是第一个Integer类型的对象作为键和值,以及如何使用类型转换异常来驱动我们的应用程序
类似的原因是为什么将非通用集合和地图与通用集合混合是不安全的。
正如我们已经看到这会使得泛型无用,因此决定(作为主要原因之一)使其成为编译时错误