源码实现
ArrayList是个泛型类
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
内部使用 Object数组存储元素:
transient Object[] elementData;
并在以下方法中将其转换为 E 类型。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
为什么不能使用E[]
Java 泛型要达到的效果:对于 ArrayList<E> 这样的类型,我们期望ArrayList<String>表现为:每次出现 E,则替换为 String 。换句话说以下代码:
private Object[] elementData = new Object[size];
public E get(int i) {
return (E) elementData[i];
}
String str = list.get(0);
应该变成这样:
private Object[] elementData = new Object[size];
public String get(int i) {
return (String) elementData[i];
}
String str = list.get(0);
但实际上并不是这样工作的。为了向后兼容,Java 泛型是通过类型删除实现的,其中 E实际上被替换为Object,并转换为 String。这意味着代码实际上变成了这样:
private Object[] elementData = new Object[size];
public Object get(int i) {
return elementData[i];
}
String str = (String) list.get(0);
投向(E)已经消失,并重新出现在调用站点。如果调用站点忽略了结果,则类型转换将完全消失!这就是它给出“未检查”警告的原因。
现在想象一下如果elementData有类型E[],也就是说,代码如下所示:
private E[] elementData = (E[]) new Object[size];
public E get(int i) {
return elementData[i];
}
String str = list.get(0);
我们知道由于擦除,它会变成与上面相同的东西。但是如果我们像我们希望的那样具体化了泛型,它会看起来像这样:
private String[] elementData = (String[]) new Object[size];
// ClassCastException: Object[] is not a String[]
本质上,我们已经编写了一些应该在运行时崩溃的代码
(未完待续。。。。)