0
  T[] genericArray= (T[])(new Object[2]);

T has a constraint that it implements Comparable. The line above fails with an exception

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

How do I initialize a generic array where the T has constraints?

4
  • Please check that answer: stackoverflow.com/a/18292315/524743 Commented Sep 17, 2015 at 13:08
  • Why do you need an array of type T[]? Commented Sep 17, 2015 at 13:17
  • I used an array of type T because later on in the code I do T[0] =...,T[1]=.. and so on. I need to return a collection of objects that are all of type T. Does not have to be an array. Any collection would do. Commented Sep 17, 2015 at 13:30
  • There is no need for the array to be of type T[] when all you want to do is array[…] = …;. An array of type Object[] will support this too. For all other operations, a collection, most likely an ArrayList will serve much better. Commented Sep 17, 2015 at 13:40

2 Answers 2

3

Object doesn't implements Comparable.

Instead of creating it as Object[] create it as Comparable[].

Related to your comment:

A variable can be declared of any type. When you create an array you are not creating objects inside the array, but you are only allocating the memory to store the references to the objects.

So as you can write:

Comparable x = "Pippo"; // Because String is Comparable

you can also write

Comparable[] x = new Comparable[1];
x[0] = "Pippo";    // Here you add a concrete String that is a
                   // Comparable type on the first position
Sign up to request clarification or add additional context in comments.

7 Comments

How? You cannot create an instance of an interface.
You can create an array of interfaces. But you need to add concrete elements inside it. For example Comparable[] x = new Comparable[1]; x[0] = "This is comparable";
From your first sentence, you might be missing the context of the question (which is that (T[])new Object[n] is a common way to create an array "of the generic type")
T could have any constraint on it. Is there a way not to enforce all those constraints again?
Wich constraints are you saying?
|
1

You get this error because Object does not implement Comparable and thus Object[] is not a sub-type of Comparable[] (which, because of type erasure, is the runtime type of your genericArray).

The underlying problem is that you want to create a generic array. This is not possible in Java. The reason is, that unlike generics, the type of the elements of an array is known at runtime. If you write new T[], it is not known which type of array must be created.

You try to circumvent this by creating an array of some supertype. But this is also not correct (and you should get a warning if you do it). If you create a an array with new Comparable[size], you create a an array of Comparables, not an array of some subtype of Comparable. A T[] might be a String[] or a Long[], and String[] and Long[] are different types than Comparable[] (also at runtime).

To demonstrate the problem, consider the following program:

public class Foo<T extends Comparable> {    
    T[] createArray() {
        return (T[])new Comparable[1];
    }

    public static void main(String... args) {
        Foo<String> foo = new Foo<>();
        String[] ss = foo.createArray(); // here
    }
}

It might look perfectly okay at first sight, but when your run it, you get a ClassCastException, because in the marked line a Object[] is cast to a String[].

The solution is to use Class<T> objects as so-called type tokens. These let you store the type so that you can access it at run-time. Now you can create an array with the correct type by using Array.newInstance(Class<T>, int...). For example:

public class Foo<T extends Comparable> {
    private Class<T> type;

    public Foo(Class<T> type) {
        this.type = type;
    }

    T[] createArray() {
        return (T[])Array.newInstance(type, 1);
    }

    public static void main(String... args) {
        Foo<String> foo = new Foo<>(String.class);
        String[] ss = foo.createArray();
    }
}

(You may still get a warning from the compiler, because newInstance's return type is Object. You can ignore it because the object it returns is an array of the correct type.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.