java - 通用阵列非常规类型转换

标签 java arrays generics

我正在构建一个通用的 HashTable 类,在该类中我们使用简单的 Java .hashCode() 方法将键转换为散列,以数组大小为模,并将结果存储在索引中。唯一的问题是教授希望我们不仅要存储值,还要存储散列后的 key 。为此,我创建了一个存储和获取这两个值的数据类:

private class Data {
    private K key;
    private V value;

    public Data(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }
}

很简单的东西。当我尝试创建数据项数组来保存散列值和生成它们的键时,困难就来了。 K 和 V 是 HashTable 类声明中指定的通用值:

public class HashTable<K,V> implements Table<K,V>

当我第一次创建该类时,我只是对对象数组使用强制转换来创建一个 V 数组,但由于我们需要存储这两个值,所以我决定创建 Data 类并存储它们。但是当我尝试用我的

hashArray = (Data[])new Object[arraySize];

它给了我错误

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lproject3.HashTable$Data;

这使我无法创建数据类型的数组。有没有另一种方法可以在不使用列表的情况下存储它(因为这是分配的参数)?

最佳答案

Object[]不是 Data[] .转换必然会在运行时失败。但是既然类型在那里已经知道了,为什么不直接创建一个Data[]呢? ?创建 Object[] 是没有意义的并尝试施放它。

现在回答你的另一个问题,下面的 Actor :

V[] arr = (V[]) new Object[arraySize];

有效,因为 V 的类型在运行时是未知的。类型信息被删除。并且由于类型参数的删除是最左边的绑定(bind),在本例中为 Object ,上面的转换在运行时看起来像这样:

Object[] arr = (Object[]) new Object[arraySize];

看起来不错,不是吗?但是,一旦您让数组转义您的类并将返回值分配给任何引用,这种方式也会失败:

HashTable<String, Integer> map = new HashTable<String, Integer>();
// suppose you have a getter to get the array stored
Integer[] arr = map.getValueArray();

上面的第二行会抛出一个 ClassCastException在运行时出于与上面发布的相同的原因。所以,类型转换一个 Object[]V[]将工作,直到你不让数组逃脱类。

现在,考虑另一种情况,您给 V 一个边界,说 V extends Comparable<V> ,看看会发生什么;

public class MyClass<T extends Comparable<T>> {
    T[] arr;

    public MyClass() {
        arr = (T[])new Object[0];
    }
}

在这种情况下,删除类型参数 TComparable ,因此构造函数中的转换被删除为:

arr = (Comparable[]) new Object[0];

这将再次抛出 ClassCastException ,无论您是否让数组转义该类。

所以,重点是,在创建泛型数组时需要非常小心。


另见:

关于java - 通用阵列非常规类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21808001/

相关文章:

java - Java 获取一系列值的方法

java - 如何使用用户给出的参数调用静态方法(反射)

java - 平衡 Java J2EE 服务器上 CPU/内存资源的线程使用

java - 无法在 onComplete 方法中设置适配器 Facebook SDK,ANDROID

java - Java 程序如何检测到 MacOS 机器正在关闭?

swift - 参数类型 'T.Type' 不符合预期类型 'Comparable'

python - np.ascontiguousarray 与 np.asarray 与 Cython

c++ - 将元素从 list<string>mylist 复制到字符串 mystr

java - 合并排序算法逻辑的合并功能是错误的

c# - 在 C# 中将通用集合转换为 JSON