泛型和创建可比较对象 (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
个元素的数组,该数组可以容纳 Comparable
或 Comparable
的任何子类型。没有创建 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)
初始化。
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
个元素的数组,该数组可以容纳 Comparable
或 Comparable
的任何子类型。没有创建 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)
初始化。