简体   繁体   中英

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.

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.

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?

new Comparable[N] creates an array with N elements which can hold Comparable or any subtype of Comparable . No Comparable is created, just an array.

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. However, the cast to T[] is unchecked, which means it doesn't happen at the particular point where the cast expression is. Instead, the cast is erased and somewhere else, outside of your ArrayHeap class, there's some code like this:

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.

The point, though, is that you don't actually get a T[] when you do (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. If you tried to return the Comparable[] to the outside world as a T[] you'll get an exception.

It's creating an array that can hold Comparable objects. The important point is that the array is only allowed to hold Comparable objects; new Object[capacity] would be allowed to hold anything.

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 ). Since T is required to implement Comparable , the next best thing is an array of Comparable .

This is still awkward, though, and you'll get a warning from your compiler about use of Comparable as a raw type. It'd be better to define heap as a List<T> , and initialize it with new ArrayList<>(capacity) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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