创建一个包含Java Generics的新数组

时间:2016-04-08 14:25:54

标签: java generics

我正在开发一个用于教授泛型的大案例。一组模仿Java中集合类的类和接口。这是源文件之一:

package edu.brandeis.cosi12b.listdemo;

public class ArrayList<E extends Comparable<E>> extends AbstractList<E> implements List<E> {
  private E[] list;
  private int size;
  private int capacity;

  public ArrayList() {
    this(20);
  }

  @SuppressWarnings("unchecked")
  public ArrayList(int initialCapacity) {
    list = (E[]) (new Object[initialCapacity]);
    size = 0;
    capacity = initialCapacity;
  }

  public int capacity() {
    return capacity;
  }

  public int size() {
    return size;
  }

  public void add(E val) {
    list[size] = val;
    size++;
  }

  public String toString() {
    StringBuffer s = new StringBuffer();
    s.append("[");
    for (int i = 0; i < size - 1; i++) {
      s.append(list[i]);
      s.append(", ");
    }
    s.append(list[size - 1]);
    s.append("]");
    return (s.toString());
  }

  public void set(int index, E value) {
    expandIfNecessary(index);
    for (int i = size; i > index; i--) {
      list[i] = list[i - 1];
    }
    list[index] = value;
    if (index > size)
      size = index + 1;
  }

  @SuppressWarnings("unchecked")
  private void expandIfNecessary(int index) {
    if (index < capacity)
      return;
    int newCapacity = capacity * 2 + index;
    E[] oldArray = list;
    list = (E[]) (new Object[newCapacity]);
    for (int i = 0; i < size; i++)
      list[i] = oldArray[i];
    capacity = newCapacity;
  }

  public E get(int index) {
    if (index < 0 || index >= size)
      throw new ArrayIndexOutOfBoundsException("i: " + index + " s: " + size);
    return list[index];
  }

  public void remove(int index) {
    for (int i = index; i < size; i++)
      list[i] = list[i + 1];
    size--;
  }

  public boolean isEmpty() {
    return size() == 0;
  }

  public int indexOf(E value) {
    for (int i = 0; i < size; i++) {
      if (list[i] == value)
        return i;
    }
    return -1;
  }

  public boolean contains(E value) {
    return (indexOf(value) != -1);
  }

  @Override
  public void add(int index, E value) {
    // TODO Auto-generated method stub
  }
}

当我在测试用例中运行它时,我收到此错误。我知道这是非常微妙的,它超出了我对Java的了解。

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
    at edu.brandeis.cosi12b.listdemo.ArrayList.<init>(ArrayList.java:14)
    at edu.brandeis.cosi12b.listdemo.ArrayList.<init>(ArrayList.java:9)
    at edu.brandeis.cosi12b.listdemo.TestSuite.arrayListtest1(TestSuite.java:134)
    at edu.brandeis.cosi12b.listdemo.TestSuite.runArrayListTests(TestSuite.java:15)
    at edu.brandeis.cosi12b.listdemo.TestSuite.runAll(TestSuite.java:9)
    at edu.brandeis.cosi12b.listdemo.ListDemo.runTests(ListDemo.java:13)
    at edu.brandeis.cosi12b.listdemo.ListDemo.main(ListDemo.java:6)

1 个答案:

答案 0 :(得分:6)

使用

list = (E[]) new Comparable<?>[initialCapacity];

list = (E[]) (new Comparable<?>[newCapacity]);

Java在运行时没有完全具体化的泛型(它使用擦除),所以它实际上并不知道E是什么 - 只是它扩展了Comparable,所以这就是编译器插件用于演员表。

如果反编译,编译器为您的代码生成的字节码如下所示:

list (Comparable[]) new Object[initialCapacity];

失败了。