我正在阅读这篇文章Java 泛型 http://www.ibm.com/developerworks/library/j-jtp01255/index.html那里提到了一个构造函数ArrayList
看起来有点像这样:
class ArrayList<V> {
private V[] backingArray;
public ArrayList() {
backingArray = (V[]) new Object[DEFAULT_SIZE];
}
}
我无法理解编译器的类型擦除和类型检查是如何发生的,如那里所解释的。我得到的一点是类型参数被转换为Object
type.
我将其想象为(替换所有V
with Object
),但这绝对是错误的。
class ArrayList<Object> {
private Object[] backingArray;
public ArrayList() {
backingArray = (Object[]) new Object[DEFAULT_SIZE];
}
}
具体是如何转化为Object
类型但仍保留类型安全V
?
当我有ArrayList<String>
and ArrayList<Integer>
每个类别有两个不同的类别吗?如果没有的话,类型信息在哪里String
and Integer
被储存了?
您的类型擦除版本不正确。类型参数声明不会被删除Object
但只有它的用法被删除。进一步来说:
- 泛型类型的擦除是其对应的原始类型。因此对于
ArrayList<V>
,这只是ArrayList
.
- 类型参数的擦除是其最左边的边界。
- 所有类型参数都被删除。类型参数是您在实例化泛型类时使用的参数。所以,
ArrayList<Integer>
将被替换为ArrayList
.
所以,正确的擦除版本是:
class ArrayList {
private Object[] backingArray;
public ArrayList() {
backingArray = (Object[]) new Object[DEFAULT_SIZE];
}
}
当我有 ArrayList 和 ArrayList 时,每个都有两个不同的类吗?
不,事实并非如此。编译器仅生成泛型类型或方法的一种字节码表示形式,并将泛型类型或方法的所有实例化映射到唯一表示形式。
如果不是String和Integer的类型信息存储在哪里?
当编译器执行类型擦除时,它会根据一些预定义的规则删除所有类型信息,偶尔添加所谓的桥接法,并添加所需的所有必要类型转换。
因此,例如,以下用法ArrayList<Integer>
and ArrayList<String>
:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
int value = list.get(0);
ArrayList<String> list2 = new ArrayList<String>();
list.add("A");
String value2 = list.get(0);
将被转换为类似这样的:
ArrayList list = new ArrayList();
list.add(1);
int value = (Integer) list.get(0);
ArrayList list2 = new ArrayList();
list.add("A");
String value2 = (String) list.get(0);
进一步阅读:
- Java 泛型常见问题解答 - 什么是类型擦除? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20type%20erasure?
- 为什么编译器在翻译泛型时要添加强制转换? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Why%20does%20the%20compiler%20add%20casts%20when%20it%20translates%20generics?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)