微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Java中实现ArrayList的类型擦除

我在 Java Generics上阅读这篇文章,并提到ArrayList的构造函数看起来有点像这样:
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&gt ;:::

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?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐