在下面的示例中,我尝试创建一个通用引用hm
,引用新创建的HashMap
类型<Integer,Integer>
。但即使我通过hm
引用添加字符串值也是允许的。如果参考有例如。它下面的hm1
仅在编译时抛出错误。
HashMap hm = new HashMap<Integer,Integer>();
hm.put("hello", "HashMap"); // why it is allowing even if the object created passed <Integer,Integer> else what is significance of <Integer,Integer> on object declaration
HashMap <Integer,Integer> hm1;
hm1 = hm;
hm1.put("adfasf", "adff"); // throws error
所以我的问题是为什么它允许添加具有不同数据类型的元素,即使创建的对象传递了<Integer,Integer>
否则<Integer,Integer>
对于对象声明有什么意义?
答案 0 :(得分:2)
HashMap hm = new HashMap<Integer,Integer>();
hm.put("hello", "HashMap");
Java中的泛型仅在编译时发生,它们在运行时完全没有效果。
这意味着在运行时HashMap<String, String>
与HashMap<Integer, Integer>
是同一种对象。
所有泛型所做的就是告诉编译器检查声明的类型是否合理(并且由于历史原因,这是选择加入,你可以保留泛型)。
在您的示例中,变量的类型只是原始类型HashMap
(没有任何泛型类型)。因此,编译器不会对键或值执行类型检查。 (你会得到一个警告)。
HashMap <Integer,Integer> hm1;
hm1.put("adfasf", "adff"); // throws error
与hm
相反,您的hm1
确实具有泛型类型,编译器会检查它。
请注意,它不会引发错误&#34;,(这将是一个运行时事件),但它无法编译。如果您设法编译此代码,它将无错误地运行(正如您通过hm
访问同一对象时所见)。只有当你试图再次从地图中取出一个Integer时才会出现错误(因为类型转换会在运行时失败)。
答案 1 :(得分:2)
HashMap hm = new HashMap<Integer,Integer>(); hm.put("hello", "HashMap"); // why it is allowing even if the object created passed <Integer,Integer> else what is significance of <Integer,Integer> on object declaration
因为hm
是HashMap
,而不是HashMap<Integer, Integer>
。您已为其分配了HashMap<Integer, Integer>
,但其类型为HashMap
。由于HashMap
接受键和值的任何对象,因此字符串是可接受的并且代码编译。 (由于类型擦除,它也会运行。)
HashMap<Integer,Integer> hm1; hm1 = hm; hm1.put("adfasf", "adff"); // throws error
无法编译,因为您已告诉编译器hm1
将包含哪些内容; hm1
的类型是HashMap<Integer, Integer>
,而不仅仅是HashMap
,因此编译器知道将字符串放入其中是不行的。