public class ArrayHeap<T extends Comparable<T>> implements Heap<T>{
...
public ArrayHeap(int capacity){
heap = (T[]) new Comparable[capacity];
}
您好,在线堆上有一个快速问题= ... 所以在课堂上,我们一直在讨论堆并使用数组实现它们(使用泛型类型)。只是做一些评论,无法了解第5行的实际情况。
所以我们不能创建泛型类型的对象,通常我希望看到:
heap = (T[]) new Object[capacity]
即。如果我要阅读本文及其内容:将堆设置为将新Object转换为类型为T的通用数组的结果,并将大小设置为capacity。
我的问题是,该怎么做:
heap = (T[]) new Comparable[capacity];
读?它是创建一个新的Comparable对象还是一个实现类似接口的新Object?
答案 0 :(得分:1)
new Comparable[N]
创建一个包含N
元素的数组,该数组可以包含Comparable
或Comparable
的任何子类型。没有创建Comparable
,只是一个数组。
对于投射,通常如果您执行(String[]) new Comparable[N]
之类的操作,您将获得ClassCastException
,因为它不是有效投射。但是,对T[]
的强制转换是未选中的,这意味着它不会在强制转换表达式的特定点发生。相反,the cast is erased以及您ArrayHeap
课程之外的其他地方,有一些代码如下:
ArrayHeap<String> h = ...;
String s = h.get(...);
并且在编译过程中会被替换为:
ArrayHeap h = ...;
String s = (String) h.get(...);
我们可以说它有点像(T[])
演员阵容被移动。
但重点是,当您执行T[]
时,实际上并未获得(T[]) new Comparable[N]
。您只是在欺骗编译器,以便在ArrayHeap
类的主体内为您提供更好的静态类型检查。如果您尝试将Comparable[]
作为T[]
返回外部世界,那么您将获得例外。
答案 1 :(得分:1)
它创建了一个可以容纳Comparable
个对象的数组。重要的是,数组仅允许保留Comparable
个对象; new Object[capacity]
将被允许持有任何东西。
你真正想要的是T[]
- 这意味着,数组仅限于保留堆应该使用的特定类型T
- 但是由于Java的泛型工作原理(type erasure),这是不可能的。由于T
需要实现Comparable
,因此下一个最好的事情是Comparable
数组。
但这仍然很尴尬,并且您将从编译器收到关于使用Comparable
作为原始类型的警告。最好将heap
定义为List<T>
,并使用new ArrayList<>(capacity)
对其进行初始化。