为什么原始类型引用可以引用泛型实例?

Why can a raw type reference refer to a generic instance?

请帮忙理解为什么

Map map1 = new HashMap<String,String>(); // This compiles
Map<Object,Object> map2 = new HashMap<String,String>(); // This does not.

据我了解

Map map1 

相同
Map<Object,Object> map1 

----编辑----

当没有为引用 map1 提供泛型时,编译器接受使用任何泛型创建的对象。这对我来说似乎 map1 有 implicit

<Object,Object> 

已应用仿制药。

所以这里的问题是当 map2 具有显式时编译失败的原因

<Object,Object> 

应用仿制药。

对于反对者,标记为重复的问题不会直接回答我的问题。

感谢 Chetan 和 Pham,这解释了!!!

这是因为当您使用 new HashMap<String,String>(); 时,对象只能包含字符串值。

但是变量Map<Object,Object> map2意味着map2可以包含Object键和值。

并且使用 Map<Object, Object> 与使用 Map 不同。只是后者你没有使用类型安全,前者会在编译过程中显示你的错误,而后者会在运行时抛出错误。

Map<Object,Object> map2 = new HashMap<String,String>();

As per my understanding

Map map1 is same as

Map<Object,Object> map1

没有。 MapMap<Object,Object> 不同。

类型 HashMap<T,T> 的引用是类型 Map 的引用的子类型。换句话说,Map 类型的引用可以引用 HashMap<String,String>.

类型的对象

另一方面,HashMap<T,T> 类型的引用不是 Map<E,E> 类型引用的子类型(即使 TE 并且HashMap 是一个 Map)。换句话说,Map<Object,Object> 类型的引用不能引用 HashMap<String,String> 类型的对象,即使 StringObject 并且 HashMap 是 - Map.

如果您想知道为什么在泛型情况下引用子类型的规则以这种方式工作,我可以根据我的理解给出一个解释。泛型是语法糖,一旦代码被编译就会经历所谓的 type-erasure 。也就是说,编译时 HashMap<String,String> 变成 HashMap

如果编译器允许 Map<Object,Object> map = new HashMap<String,String> 语句,它会误导程序员认为 Map 在运行时只能保存 String 键和值。这将是荒谬的,因为泛型在编译时本身会经历 type-erasure

另一方面,允许使用语句 Map map = new HashMap<String,String> 主要是为了与遗留代码向后兼容。