8

This is from Professor Mark Weiss in his book Data Structures and Algorithm Analysis in Java

public class BinaryHeap<AnyType extends Comparable<? super AnyType>>{
    private void enlargeArray( int newSize ){
        AnyType [] old = array;
        array = (AnyType []) new Comparable[ newSize ];
        for( int i = 0; i < old.length; i++ )
        array[ i ] = old[ i ];        
    }
}

I was wondering why do we declare an array with a type of interface Comparable since we have to convert the Comparable[] to an AnyType[]? Any design philosophy in there?

YCF_L
  • 49,027
  • 13
  • 75
  • 115
liuxl
  • 103
  • 5
  • This cast is outright wrong. `new Comparable[newSize]` is not an `AnyType[]`. The code shouldn't be trying to use an array of generic type at all. – user2357112 supports Monica Apr 14 '17 at 16:59
  • 3
    Because you can't create an array of type AnyType[]. – JB Nizet Apr 14 '17 at 16:59
  • See http://stackoverflow.com/questions/18581002/how-to-create-a-generic-array for more details on why generics and arrays don't mix well and why that cast is a terrible idea. – user2357112 supports Monica Apr 14 '17 at 17:02
  • "This cast is outright wrong." Too bad it's necessary, then , isn't it, @user2357112? You see this idiom in library code, for example `ArrayList`, it's so wrong. – Lew Bloch Apr 14 '17 at 17:03
  • 1
    @user2357112 it's not that wrong. The compiler will generate an unchecked cast warning, but you can't really do anything better when you have to store objects of a generic type in an array. As long as the array is private and isn't exposed, this is fine. – JB Nizet Apr 14 '17 at 17:03
  • @LewBloch: It's not necessary if you don't try to make the `array` member an `AnyType[]`. – user2357112 supports Monica Apr 14 '17 at 17:03
  • @user2357112 but then you'll have to add explicit casts every time you get an element from the array. – JB Nizet Apr 14 '17 at 17:04
  • I guess they shouldn't have done it in `ArrayList`, then. – Lew Bloch Apr 14 '17 at 17:05
  • 1
    @LewBloch they haven't :-) – JB Nizet Apr 14 '17 at 17:05
  • @LewBloch: [Hey look, they didn't!](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/ArrayList.java#ArrayList.0elementData) They used an `Object[]`. – user2357112 supports Monica Apr 14 '17 at 17:05
  • @user2357112 but they need an unchecked cast, too: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/ArrayList.java#ArrayList.elementData%28int%29 – JB Nizet Apr 14 '17 at 17:07
  • 1
    @JBNizet: Yeah, you can't get away from the unchecked cast without an explicit `Class` object, but it's still better to perform the unchecked casts on the elements (which are actually expected to have the type you're casting them to) than the array (which definitely isn't of the type you'd be casting it to). – user2357112 supports Monica Apr 14 '17 at 17:09
  • I'm referring to `return (T[]) Arrays.copyOf(elementData, size, a.getClass());`, of course, @user2357112. – Lew Bloch Apr 14 '17 at 17:15
  • 1
    @user2357112 that will work without any problem though, and at least it will cause the compiler to complain if you try storing something other than an AnyType in the array. That won't be the case if you use a Comparable[]. BTW, the class com.sun.jmx.remote.internal.ArrayQueue does use that. – JB Nizet Apr 14 '17 at 17:16
  • 1
    @LewBloch: That `Arrays.copyOf` call actually does return a real `T[]`. I don't think the `(T[])` cast is necessary. – user2357112 supports Monica Apr 14 '17 at 17:21
  • Thanks guys, such a rookie question I've asked. – liuxl Apr 15 '17 at 14:55

2 Answers2

4

The design "philosophy" is that you can't instantiate an array of a type parameter, so you have to instantiate the array with a type that is legal. The only available legal types known to the method are array of Object or of Comparable, and the latter captures more knowledge about the type.

You are allowed to downcast to an array of the type parameter, and the return type has to be that, so downcasting is required.

It's the "philosophy" of necessity.

Lew Bloch
  • 3,188
  • 1
  • 13
  • 9
0

AnyType I believe is a generic. In Java you can't create an array of generics. As a workaround for this, he has instantiated an array of Comparables (an interface) and then type-casted it to an array of generics.

If you look at this "how to create an array of generics" question, one person offers initializing an array of Objects and then type-casting to an array of the desired generic.

Diana
  • 69
  • 1
  • 8