简体   繁体   English

泛型并创建可比较的对象(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];
    }

Hi there, just have a quick question on the line heap = ... So in class, we have been discussing heaps and implementing them using arrays (using generic types). 嗨,在堆= ...上有一个简单的问题,所以在课堂上,我们一直在讨论堆,并使用数组(使用泛型类型)实现堆。 Just doing some review and can't get my head around what's actually happening here on line 5. 仅做一些检查,就无法了解第5行的实际情况。

So we cannot create objects of the generic type, normally I would expect to see: 因此,我们无法创建通用类型的对象,通常我希望看到:

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

Ie If I was to read this and what it says: Set heap to the result of casting a new Object to a generic array of type T, and set the size to capacity. 即,如果我要阅读本节及其内容:将堆设置为将新Object强制转换为类型T的通用数组的结果,并将大小设置为容量。

My question is, how can the line: 我的问题是,怎么行:

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

be read? 被阅读? Is it creating a new Comparable object or a new Object that implements the comparable interface? 是创建新的Comparable对象还是实现可比较接口的新对象?

new Comparable[N] creates an array with N elements which can hold Comparable or any subtype of Comparable . new Comparable[N]将创建一个阵列N可容纳元件Comparable或任何亚型Comparable No Comparable is created, just an array. 没有创建Comparable ,只是一个数组。

For the casting, normally if you did something like (String[]) new Comparable[N] you'll get a ClassCastException because it's not a valid cast. 对于转换,通常,如果您执行了(String[]) new Comparable[N] ,则会得到ClassCastException因为它不是有效的转换。 However, the cast to T[] is unchecked, which means it doesn't happen at the particular point where the cast expression is. 但是,对T[]的强制转换未经检查,这意味着强制转换在表达式的特定位置不会发生。 Instead, the cast is erased and somewhere else, outside of your ArrayHeap class, there's some code like this: 取而代之的是 ,将ArrayHeap类型转换删除,并且在ArrayHeap类之外的其他地方,有一些类似以下的代码:

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

and that gets replaced during compilation with something like this: 并且在编译过程中将其替换为以下内容:

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

We could therefore say that it's sort of like the (T[]) cast gets moved. 因此,我们可以说它有点像(T[])强制转换。

The point, though, is that you don't actually get a T[] when you do (T[]) new Comparable[N] . 但是,要点是,当您执行(T[]) new Comparable[N]时,实际上并没有得到T[] (T[]) new Comparable[N] You're just sort of tricking the compiler in to giving you better static type checking inside the body of the ArrayHeap class. 您只是在欺骗编译器,以便在ArrayHeap类的主体内提供更好的静态类型检查。 If you tried to return the Comparable[] to the outside world as a T[] you'll get an exception. 如果您尝试将Comparable[]作为T[]返回给外界,则会出现异常。

It's creating an array that can hold Comparable objects. 它正在创建一个可以容纳Comparable对象的数组。 The important point is that the array is only allowed to hold Comparable objects; 重要的一点是, 允许数组容纳Comparable对象。 new Object[capacity] would be allowed to hold anything. new Object[capacity]将被允许​​容纳任何东西。

What you really want is a T[] — meaning, the array is limited to holding only the specific type T that the heap is supposed to be working with — but that's not possible because of how Java's generics work ( type erasure ). 真正想要的是一个T[] -意味着,该数组仅限于容纳应该与堆一起使用的特定类型T但这是不可能的,因为Java的泛型是如何工作的( 类型擦除 )。 Since T is required to implement Comparable , the next best thing is an array of Comparable . 由于T是实现Comparable所必需的,因此,下一个最好的事情是Comparable的数组。

This is still awkward, though, and you'll get a warning from your compiler about use of Comparable as a raw type. 但是,这仍然很尴尬,并且您会从编译器收到有关将Comparable用作原始类型的警告。 It'd be better to define heap as a List<T> , and initialize it with new ArrayList<>(capacity) . 最好将heap定义为List<T> ,并使用new ArrayList<>(capacity)对其进行初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM