好吧,我一直在谷歌上网,我似乎无法找到任何问题的解决方案.我找到了很多解决方案,而不是任何合适的解决方案.
我需要创建一个泛型数组.但泛型类型本身扩展了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;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是Object不能被强制转换为扩展Comparable的泛型.有没有解决的办法?
cle*_*tus 78
基本上,泛型和数组不会混合.简短的回答是你可以解决这个问题.更长的答案是你可能不应该,我会解释原因.
你可以Array.newInstance()像这样使用:
private Comparable[] hashtable;
...
hashtable = (Comparable[])Array.newInstance(Comparable.class, tableSize);
Run Code Online (Sandbox Code Playgroud)
但是您无法创建参数化类型的数组.
数组是协变的.这意味着它们在运行时保留其元素的类型.Java的泛型不是.他们使用类型擦除来基本掩盖正在进行的隐式转换.理解这一点很重要.
因此,当您创建一个Object数组时,您无法将其强制转换为Comparable数组(或任何其他类型),因为这是不正确的.
举个例子.使用泛型,这是完全合法的:
List<String> list = new ArrayList<String>();
List<Integer> list2 = (List<Integer>)list;
list.add(3);
Run Code Online (Sandbox Code Playgroud)
这也是你不能这样做的原因:
public <T> T newInstance(T t) {
return new T(); // error!
}
Run Code Online (Sandbox Code Playgroud)
即在运行时,不知道T的类.这就是为什么上面的代码更常被写为:
public <T> T newInstance(T t, Class<T> clazz) {
return clazz.newInstance();
}
Run Code Online (Sandbox Code Playgroud)
因为它们不是泛型参数的运行时类型.但是对于数组:
String arr[] = new String[10];
Integer arr2[] = (Integer[])arr; // error!
Run Code Online (Sandbox Code Playgroud)
在这种情况下你应该做什么(imho)不是使用数组而是使用数组ArrayList.老实说,没有什么理由可以使用数组ArrayList而且泛型就是其中的一个例子.
有关更好和更完整的解释,请参阅(优秀)Java泛型常见问题解答:
我可以创建一个组件类型是具体参数化类型的数组吗?
不,因为它不是类型安全的.
数组是协变的,这意味着超类型引用数组是子类型引用数组的超类型.也就是说,
Object[]是一个超类型,String[]并且可以通过类型的引用变量访问字符串数组Object[]....
mat*_*att 16
这里的其他答案通常都提倡更好的方法(特别是建议使用ArrayList),但在这个特定情况下的一个简单答案可能是:
hashTable = (T[])(new Comparable[tableSize]);
Run Code Online (Sandbox Code Playgroud)
(即创建一个类型为raw Comparable而不是Object的数组)
如果你在Hash对象中正确封装了对这个数组的所有访问权限,这应该有效,但是(正如其他答案所解释的那样)你可能会让自己变得脆弱.
| 归档时间: |
|
| 查看次数: |
53751 次 |
| 最近记录: |