bra*_*orm 12 java generics constructor arraylist object
我正在阅读关于Java Generics的这篇文章,并且在那里提到了一个ArrayList看起来像这样的构造函数:
class ArrayList<V> {
private V[] backingArray;
public ArrayList() {
backingArray = (V[]) new Object[DEFAULT_SIZE];
}
}
Run Code Online (Sandbox Code Playgroud)
我无法理解编译器的类型擦除和类型检查是如何解释的那样.我得到的一点是type参数转换为Objecttype.
我将它想象成(更换所有V带Object),但是这肯定是不对的.
class ArrayList<Object> {
private Object[] backingArray;
public ArrayList() {
backingArray = (Object[]) new Object[DEFAULT_SIZE];
}
}
Run Code Online (Sandbox Code Playgroud)
它究竟是如何转变为Object类型但仍保留类型安全性的V?当我有ArrayList<String>和ArrayList<Integer>是否有两种不同类型的每一个?如果没有,在哪里类型的信息String和Integer存储?
您的类型擦除版本不正确.类型参数声明不会被删除,Object只会删除它的用法.进一步来说:
ArrayList<V>,它只是ArrayList.ArrayList<Integer>将被取代ArrayList.所以,正确的擦除版本将是:
class ArrayList {
private Object[] backingArray;
public ArrayList() {
backingArray = (Object[]) new Object[DEFAULT_SIZE];
}
}
Run Code Online (Sandbox Code Playgroud)
当我有ArrayList和ArrayList时,每个都有两个不同的类?
不,情况绝对不是这样.编译器仅生成泛型类型或方法的一个字节代码表示,并将泛型类型或方法的所有实例映射到唯一表示.
如果没有存储String和Integer的类型信息的位置?
当编译器执行类型擦除时,它会根据一些预定义的规则删除所有类型信息,偶尔添加所谓的桥接方法,并添加所需的所有必要类型转换.
因此,例如,以下用法ArrayList<Integer>和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);
Run Code Online (Sandbox Code Playgroud)
将转换为有点像这样:
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);
Run Code Online (Sandbox Code Playgroud)
进一步阅读: