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

标签 java generics reference generic-collections raw-types

<分区>

请帮忙理解原因

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 有隐含的

<Object,Object> 

应用了泛型。

所以这里的问题是当map2有显式时为什么编译失败

<Object,Object> 

应用了泛型。

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

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

最佳答案

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> 类型引用的子类型(即使 T 是一个 EHashMap 是一个 Map )。换句话说,类型为 Map<Object,Object> 的引用不能引用 HashMap<String,String> 类型的对象即使String是一个ObjectHashMap是一个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>另一方面,主要是为了与遗留代码向后兼容。

关于java - 为什么原始类型引用可以引用泛型实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30748976/

相关文章:

c++ - cpp中的字符串引用处理

java访问客户端文件系统

c# - 方法中的泛型,c#

c# - 除了 System.Type 之外没有任何更多信息的 Cast 对象

c++ - 我们是否需要删除对非新对象的引用?

c++ - 使用存储在 vector 中的对象的正确方法是什么?

java - 我有 JAXB 类加载器泄漏吗

java - Flink runner 上的 Beam : ClassNotFoundException: org. apache.beam.runners.flink.translation.wrappers.streaming.WorkItemKeySelector

java - 如何在多个参数上动态构建 JDO 查询

c# - Foo<T> 其中 T 是接口(interface)或实现