【问题标题】:Generic Array Unconventional Casting通用数组非常规铸造
【发布时间】:2014-02-16 06:17:29
【问题描述】:

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

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;

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

【问题讨论】:

  • 考虑查看java.util.HashMap 的实现并检查他们如何处理它。

标签: java arrays generics


【解决方案1】:

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

现在回答你的另一个问题,下面的演员表:

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

有效,因为V 的类型在运行时未知。类型信息被删除。并且由于类型参数的擦除是它的最左边界,在这种情况下是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&lt;V&gt;,看看会发生什么;

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

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

在这种情况下,类型参数T的擦除为Comparable,因此构造函数中的强制转换被擦除为:

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

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

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


另见

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多