这些初始化HashMap的方法有什么区别?

我为我的程序使用了HashMap,它工作正常,但我不明白这些HashMap初始化之间的区别。

假设我正在实现一个HashMap,其中一个字符作为键,一个整数作为值。 这些有什么区别?

HashMap alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); Map alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); Map alphabet1 = new HashMap(); 

任何涉及没有类型参数的HashMapMap (尖括号<和>以及它们之间的部分)都是原始类型,不应使用 。 原始类型不是通用的,可以让您做出不安全的事情。

“正确”的方式是

 Map alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); 

第一个使用接口Map作为引用类型。 它通常更具惯用性和良好的风格 。

另一种方法是你没有提到, 使用Java 7钻石操作符

 Map alphabet1 = new HashMap<>(); HashMap alphabet1 = new HashMap<>(); 

这或多或少等同于前两种正确的方法。 左侧的引用类型的参数隐式提供给右侧的构造函数。

你错过了正确的选择:

 Map alphabet1 = new HashMap(); 
  1. generics声明允许编译器在编译期间检查“alphabet1”用法。
  2. 左侧的Map / HashMap声明了如何考虑’alphabet1’变量:作为Map(接口)或HashMap(具体类的实例)。 当然首选接口 – 它使您的代码对进一步更改更加健壮。
 HashMap alphabet1 = new HashMap(); // (1) 

(1)在不使用generics的情况下初始化HashMap ,但之后使用带有generics的HashMap进行不安全的HashMap 。 这应该引发编译器警告。

 HashMap alphabet1 = new HashMap(); // (2) 

(2)用generics初始化HashMap ,并用generics声明HashMap类型的变量。 它可以简称为

 HashMap alphabet1 = new HashMap<>(); // (2b) 

这里,编译器使用类型推断从左侧的声明推断HashMap的genrics。

 HashMap alphabet1 = new HashMap(); // (3) 

(3)用generics初始化HashMap,但变量alphabet1不重用generics信息。 因此,您无法以通用方式访问此HashMap值的方法(例如,在调用alphabet1.get('a')而不是强制转换为Integer时,您将获得一个转换为java.lang.Object的值)。

 Map alphabet1 = new HashMap(); // (4) 

(4)类似于(3)但是在这里, alphabet1是用Map而不是HashMap键入的。 因此,您无法访问在HashMap中定义的方法,也无法访问其超级接口Map定义的方法。

 HashMap alphabet1 = new HashMap(); // (5) 

(5)类似于(3),它不使用generics来初始化HashMap

 Map alphabet1 = new HashMap(); // (6) 

(6)类似于(4)并且不使用generics来初始化HashMap