java - 创建一个包含 Java 泛型的新数组

标签 java generics

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

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)

最佳答案

使用

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

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

Java 在运行时没有完全具体化的泛型(它使用删除),因此它实际上不知道 E 是什么 - 只是它扩展了 Comparable,这就是编译器为强制转换插入的内容。

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

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

失败了。

关于java - 创建一个包含 Java 泛型的新数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36502147/

相关文章:

java - 如何使用 JDBC 从数据库中检索 SDO_GEOMETRY?

java - 如何在Java/MySQL中实现Approximate_string_matching(模糊字符串搜索)?

java - 如何使用泛型使语句正确

C++ 限制泛型中的类型(和指针问题)

java - Java 中的线程局部变量与局部变量

java - 使用 Bean 验证时防止内部服务器错误

java - 数组与变量方法调用相比

Java 流利的构建器和继承

c# - 同一列表中的多个泛型类型并调用它们的方法

java泛型方法