【发布时间】:2020-11-01 14:01:47
【问题描述】:
我正在尝试各种实例化 HashMap 的方法,但我遇到了一个问题。 在创建从 String 到 String 的映射时,可以在以下选项中进行选择:
Map<String, String> map = new HashMap<String, String>();
Map<String, String> map = new HashMap<>();
Map<String, String> map = new HashMap();
我认为使用第一个的好处是将内存中的整个对象绑定到键和值的字符串类型,因为引用(映射)将指向 HashMap
运行以下代码不会引发错误并显示合理的输出:
Map<String, String> map = new HashMap<String, String>();
map.put("hi", "there");
Map map2 = map;
map2.put(5, 4);
System.out.println(map.get("hi"));
System.out.println(map2.get("hi"));
System.out.println(map2.get(5));
System.out.println(map2.get(5).getClass());
System.out.println(map.size());
输出是:
there
there
4
class java.lang.Integer
2
我们可以清楚地看到,两个引用都指向内存中的同一个对象,我认为它的类型应该是 HashMap
我的问题是,既然参数化的构造函数对于存储在内存中的对象来说并不重要,我们为什么要重复右侧的类型呢? 为什么要写这个:
Map<String, String> map = new HashMap<String, String>();
代替这个:
Map<String, String> map = new HashMap();
即使效果一样?
【问题讨论】:
-
“我认为应该是
HashMap<String, String>类型的” - 没有这样的东西。在执行时,只有一个HashMap。至于你为什么不使用原始类型:因为这意味着你甚至没有获得编译时类型安全。 (我希望您届时会收到警告。) -
这种编写初始化的方式:
Map<String, String> map = new HashMap<String, String>();被缩写为Map<String, String> map = new HashMap<>();,因为键、值类型已经在等号的左侧声明。这意味着以一种或另一种方式编写是相同的。今天的 IDE 会将其标记为不必要。 -
@JonSkeet 当写 Map
map = new HashMap();我仍然得到编译时安全,我在问为什么我们也应该在右侧添加类型 -
@Victor:不,你没有。您正在将“某种映射”(原始
HashMap类型)分配给类型化变量。这就是为什么你会收到警告。 (“注意:Test.java 使用未经检查或不安全的操作。”)我强烈建议改用“菱形运算符”形式 (new HashMap<>()),并养成在任何地方都避免使用原始类型的习惯。 -
@JonSkeet 我明白了,谢谢!
标签: java oop collections polymorphism