繁体   English   中英

HashMap中的泛型似乎不能始终如一地使用

[英]Generics in HashMap dont seem to be used consistently

首先是泛型的新手。 现在提问 - 在HashMap.java中我看到以下内容 -

 transient Entry[] table; 
 which is initiated in constructor as
 table = new Entry[capacity];

为什么没有使用类型参数声明?

要么

 private V getForNullKey() {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {

为什么使用类型参数声明for循环中的Entry?

有一个深刻的概念或只是一个负担得起的不一致?

那是因为创建具体参数化类型的数组不是类型安全的,这就是为什么根本不允许这样做的原因。

如果您尝试这样的代码,您将收到编译器错误:

List<String>[] arr = new ArrayList<String>[10]; // Compiler error: Generic Array creation

问题是泛型类型是不可重新生成的 - 它们的类型信息在运行时不可用。 同时,数组使用运行时可用的类型信息来执行ArrayStoreCheck以查看插入到数组中的元素是否与数组的类型兼容。 因此,如果混淆数组和泛型,那么最终可能会在运行时出现令人惊讶的行为。

例如,请考虑以下代码:

List<String>[] arr = new ArrayList<String>[10];  // Suppose this was valid
Object[] objArr = arr;         // This is valid assignment. A `List[]` is an `Object[]`
objArr[0] = new ArrayList<Integer>();  // There you go. A disaster waiting at runtime.

String str = arr[0].get(0);    // Assigned an `Integer` to a `String`. ClassCastException

因此,如果编译了第一个赋值,那么编译器看起来很好的第4个赋值将在运行时抛出ClassCastException


但是,您可以创建一个原始类型数组 - ArrayList或无界通配符参数化类型 - ArrayList<?> ,因为它们都是完全可再生类型。 所以以下数组创建是有效的:

List[] arr = new ArrayList[10];
List<?>[] arr2 = new ArrayList<?>[10];

由于没有与原始类型或无界通配符类型相关联的类型信息,因此在运行时不会丢失任何内容。 因此这些类型是可以恢复的,它们是数组的合格组件类型。 这就是使用Entry[]而不是Entry<K, V>[]


也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM