好的,我一直在Google搜索网络,但似乎找不到解决我问题的任何方法。我找到了很多解决方案,但都不合适。
我需要创建一个泛型数组。但是泛型类型本身扩展了Comparable。当我尝试以下操作时:
public class Hash<T extends Comparable<String>> { private T[] hashTable; private int tableSize; Hash(int records, double load) { tableSize = (int)(records / loadFactor); tableSize = findNextPrime(tableSize); hashTable = (T[])(new Object[tableSize]); //Error: Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable; } }
问题在于对象不能转换为扩展Comparable的泛型。有没有解决的办法?
泛型和数组基本上不混合。简短的答案是你可以解决此问题。较长的答案是你可能不应该这样做,我将解释原因。
你可以这样使用Array.newInstance():
Array.newInstance()
private Comparable[] hashtable; ... hashtable = (Comparable[])Array.newInstance(Comparable.class, tableSize);
但你无法创建参数化类型的数组。
数组是协变的。这意味着它们在运行时保留其元素的类型。Java的泛型不是。他们使用类型擦除基本上掩盖了正在进行的隐式转换。了解这一点很重要。
因此,当你创建Object数组时,不能将其强制转换为Comparable数组(或任何其他类型),因为这是不正确的。
举个例子。对于泛型,这是完全合法的:
List<String> list = new ArrayList<String>(); List<Integer> list2 = (List<Integer>)list; list.add(3);
这也是为什么你不能这样做的原因:
public <T> T newInstance(T t) { return new T(); // error! }
即在运行时不了解T的类。这就是为什么上面的代码通常写为:
public <T> T newInstance(T t, Class<T> clazz) { return clazz.newInstance(); }
因为它们不是泛型参数的运行时类型。但是使用数组:
String arr[] = new String[10]; Integer arr2[] = (Integer[])arr; // error!
在这种情况下(imho),你应该执行的操作不是使用数组,而是使用ArrayList。老实说,在an上使用数组的理由很少,ArrayList而泛型只是其中的一个例子。
ArrayList
有关更好和更完整的解释,请参阅(优秀)Java Generics FAQ:
我可以创建一个组件类型为具体参数化类型的数组吗? 不可以,因为它不是类型安全的。
数组是协变的,这意味着超类型引用的数组是子类型引用的数组的超类型。也就是说,Object[]是的超类型,String[]可以通过type的引用变量访问字符串数组Object[]。
Object[]
String[]
…