为什么我不能初始化自定义类的数组

时间:2016-08-19 23:02:01

标签: java arrays generics classcastexception

我正在尝试用Java实现一个基本的hashmap,并且我坚持为什么我不能声明我的自定义类KVPair的数组。在我的构造函数中修复数组声明的多次尝试之后,我收到一个错误:

contains = new KVPair[capacity];

当我尝试这个时,我收到一个编译错误,说我无法创建HashMap.KVPair的通用数组。"

我还从另一个stackexchange回答中看到,建议将对象数组转换为其他类似的东西:

contains = (KVPair[])new Object[capacity];

当我这样做时,我得到一个运行时错误,说" java.lang.ClassCastException:[Ljava.lang.Object;无法转换为[MyHashMap $ KVPair;。"

下面我已经包含了我的hashmap类的一个构造函数以及我的KVPair类。如何解决这个问题的任何帮助将不胜感激。

public class MyHashMap<K, V> implements Iterable<K> {

private static final int DEFAULT_CAPACITY = 200;
private static final double DEFAULT_LOAD_FACTOR = 0.7;

private int capacity; // the number of buckets in the map
private int size; // the number of items that have been put into the map
private double loadFactor;

KVPair[] contains;

// Constructs an empty map.
public MyHashMap() {
    capacity = DEFAULT_CAPACITY;
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    contains = (KVPair[]) new Object[capacity];
}

... 

public class KVPair {
    private K key;
    private V value;
    private KVPair next;
    private int hash;
    private KVPair(Object k, Object v){
        key = (K) k;
        value = (V) v;
        next = null;
        hash = k.hashCode();
    }
    public KVPair(Object k, Object v, KVPair nextKV){
        key = (K) k;
        value = (V) v;
        next = nextKV;
        hash = k.hashCode();
    }

}

1 个答案:

答案 0 :(得分:0)

通常,需要底层通用数组的集合的实现通过使用类型为cublasSetMatrix()的非泛型数组来解决此问题。只要数组作为实现细节隐藏,并且集合公开的方法都是通用的,那么这样做是完全类型安全的。您可以在JDK代码中看到它(例如:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/ArrayList.java#ArrayList)。

实例化通用数组的另一个解决方案是使用Object[]。但是,这需要传递通用类型的类,您很可能不希望强加给API的用户。只是为了记录,这里可以用来创建一个通用的数组工厂方法:

Array.newInstance

简而言之:

  • 如果您的通用数组可以作为实现细节隐藏,请使用裸public class ArrayUtils { @SuppressWarnings("unchecked") public static <T> T[] ofDim(Class<T> clazz, int length, T defaultValue) { T[] arr = (T[]) Array.newInstance(clazz, length); for (int i = 0; i < length; i++) arr[i] = defaultValue; return arr; } }
  • 如果您的通用数组将被传递并且可能被外部类突变,则需要使用Object[]确保运行时类型安全
相关问题