泛型和创建可比较对象 (Java)

Generics and creating a comparable object (Java)

public class ArrayHeap<T extends Comparable<T>> implements Heap<T>{
 ...

public ArrayHeap(int capacity){
        heap = (T[]) new Comparable[capacity];
    }

您好,请在 heap = ... 线上快速提问 所以在class中,我们一直在讨论堆并使用数组(使用泛型)来实现它们。只是做了一些审查,无法了解第 5 行这里实际发生的事情。

所以我们不能创建通用类型的对象,通常我希望看到:

heap = (T[]) new Object[capacity]

即如果我要阅读这篇文章及其内容:将堆设置为将新对象转换为类型 T 的通用数组的结果,并将大小设置为容量。

我的问题是,怎么能行:

 heap = (T[]) new Comparable[capacity];

读懂了吗?它是创建一个新的 Comparable 对象还是一个实现了可比较接口的新对象?

new Comparable[N] 创建一个包含 N 个元素的数组,该数组可以容纳 ComparableComparable 的任何子类型。没有创建 Comparable,只是一个数组。

对于转换,通常如果你做了类似 (String[]) new Comparable[N] 的操作,你会得到一个 ClassCastException,因为它不是有效的转换。但是,未检查对 T[] 的转换,这意味着它不会发生在转换表达式所在的特定点。相反,the cast is erased 和其他地方,在你的 ArrayHeap class 之外,有一些这样的代码:

ArrayHeap<String> h = ...;
String s = h.get(...);

并且在编译过程中被替换为如下内容:

ArrayHeap h = ...;
String s = (String) h.get(...);

因此我们可以说这有点像 (T[]) 演员被移动了。

不过,关键是当您执行 (T[]) new Comparable[N] 时,您实际上并没有得到 T[]。您只是在欺骗编译器,让编译器在 ArrayHeap class 的主体内为您提供更好的静态类型检查。如果您尝试将 return Comparable[] 作为 T[] 对外公开,​​您将遇到异常。

它正在创建一个可以容纳 Comparable 个对象的数组。重点是数组 允许保存 Comparable 个对象; new Object[capacity] 将被允许持有任何东西。

真正想要的是一个T[]——意思是,数组仅限于保存堆应该保存的特定类型T正在使用 — 但这是不可能的,因为 Java 的泛型是如何工作的 (type erasure)。由于 T 是实现 Comparable 所必需的,下一个最好的是 Comparable.

的数组

不过这仍然很尴尬,编译器会警告您将 Comparable 用作原始类型。最好将heap定义为List<T>,并用new ArrayList<>(capacity)初始化。