class ArrayList<V> { private V[] backingArray; public ArrayList() { backingArray = (V[]) new Object[DEFAULT_SIZE]; } }
我无法理解如何解释编译器的类型擦除和类型检查.我得到的一点是,type参数被转换为Object类型.
我会想像它(用Object替换所有V),但这绝对是错误的.
class ArrayList<Object> { private Object[] backingArray; public ArrayList() { backingArray = (Object[]) new Object[DEFAULT_SIZE]; } }
它如何转换为对象类型,但仍然保留V的类型安全?
当我有ArrayList< String>和ArrayList< Integer>每个都有两个不同的班级吗?如果不是,存储String和Integer的类型信息在哪里?
解决方法
>通用类型的擦除是其相应的原始类型.因此,对于ArrayList V,它将只是ArrayList.
>类型参数的擦除是其最左边界.
>所有的类型参数都被删除.类型参数是在实例化泛型类时使用的参数.所以,ArrayList< Integer>将被ArrayList替换.
所以,正确的擦除版本将是:
class ArrayList { private Object[] backingArray; public ArrayList() { backingArray = (Object[]) new Object[DEFAULT_SIZE]; } }
when I have ArrayList and ArrayList are there two different classes for each?
不,这是永远不会的.编译器只生成通用类型或方法的一个字节代码表示,并将通用类型或方法的所有实例映射到唯一表示.
if not where the type information of String and Integer is stored?
当编译器执行类型擦除时,它将根据一些预定义的规则删除所有类型的信息,偶尔添加所谓的bridge方法,并添加所需的所有必需的类型转换.
因此,例如,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);
将被转换为有点像这样:
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 Generics FAQs – What is Type Erasure?
> Why does compiler adds cast while translating generics?