Aku
Aku

Reputation: 200

How to avoid cast error generated by comparable interfaces

I have a generics class in Java:

public class PriorityList<T extends Number> implements Comparable<T> {  

    T[] array = (T[]) new Object[10];

And I have an error

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Number;

Error is make by this casting (T[]) new Object[10].

I need compare methods because I need the array elements must be sorted. So I can't declare class like this

public class PriorityList<T extends Number> 

Other options which have some sense is make by my own linked list to keep T values. But is another way to solve this casting problem

(T[]) new Object[10];

?

PS Collections are forbidden to use.

Upvotes: 1

Views: 219

Answers (4)

ɲeuroburɳ
ɲeuroburɳ

Reputation: 7120

The erasure of T is Number, so:

Number[] array = new Number[10];

will get you close enough. It's okay to store any subclass of Number (e.g. any T) in that array. (Note: that also should explain why the cast to (T[])new Object[10] aka (Number[])new Object[10] would cause the exception.)

Upvotes: 1

cahen
cahen

Reputation: 16636

Number is an Object, but Object is not a Number

This method from java.util.Arrays contains the logic you want. It can create an array of type T

    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

Upvotes: 0

Markov Unchained
Markov Unchained

Reputation: 159

You cannot cast a reserved array to a unknown typed array. I recommend you to use a array factory for T objects in this way:

public interface ArrayFactory<T extends Number> {
    T[] create(int size);
}

public class PriorityList<T extends Number> implements Comparable<T> {

    private ArrayFactory<T> factory=...;
    T[] array = factory.create(10);

Then, you can provide an implementation of an ArrayFactory to the PriorityList.

Hope this helps.

Upvotes: 0

acc15
acc15

Reputation: 1295

You can't cast array of Object into array of Number because Object array can contain object of any type - not only T type. But new T[] is incorrect due to type errasure - i.e. java runtime doesn't know about T.

One way is to make a an Object[] array.

Another way is:

public PriorityList(Class<T> type) {
    T[] a = (T[])Array.newInstance(type, 10);
}

Or, as mentioned - use Java collections - they are more generic-friendly.

Upvotes: 0

Related Questions