6

Possible Duplicate:
Java how to: Generic Array creation
Error: Generic Array Creation

I am getting this error:

Cannot create a generic array of T

This is my code (error on line 6):

1    public class HashTable<T> {
2    
3        private T[] array;
4    
5        HashTable(int initSize) {
6            this.array = new T[initSize];
7        }
8    }

I am wondering why this error is appearing and the best solution to fix it. Thanks.

UPDATE:

I adjusted my code so that the array is taking in linked lists instead, but I am getting a new error.

Here is my error:

Cannot create a generic array of LinkedList<T>

Here is my code (error on line six):

1    public class HashTable<T> {
2    
3        private LinkedList<T>[] array;
4    
5        HashTable(int initSize) {
6            this.array = new LinkedList<T>[initSize];
7        }
8    }

Is this error for the exact same reason? I was just assuming I could create generic linked lists and just store them in the array.

5
  • 1
    It might not be possible: stackoverflow.com/a/217110 (thought that's not quite the same thing) Commented May 1, 2012 at 13:38
  • 3
    stackoverflow.com/questions/529085/… Commented May 1, 2012 at 13:41
  • It's because of type erasure, see: docs.oracle.com/javase/tutorial/java/generics/erasure.html Commented May 1, 2012 at 13:42
  • You don't want an Array of linked lists - you just want a single linked list (or ArrayList) and treat that as an array! i.e. exactly as AlexR's answer. An ArrayList is a simple Collection wrapper around an array. Commented May 1, 2012 at 16:16
  • I am actually implementing a hash table (for a certain implementation) requires the array to be holding array lists. I've found that the simple casting method works best for my scenario. (LinkedList<T>[])(new LinkedList[initSize]) Commented May 1, 2012 at 16:22

3 Answers 3

8

Yes, generic arrays cannot be created. The best workaround I know is to use collections instead:

private List<T> list;

.......

list = new ArrayList<T>();
Sign up to request clarification or add additional context in comments.

2 Comments

That's not correct, as shown in my answer generic arrays can be created.
Not without (ewwwwww) reflection.
3

Generic arrays can be created via reflection (although an unsafe cast is required), you just need to pass the class as a parameter (assuming that the following method is inside a class that defines a <T> type parameter):

@SuppressWarnings("unchecked")
public T[] createArray(Class<T> klass, int size) {
    return (T[]) Array.newInstance(klass, size);
}

For example, in your case:

HashTable<Integer> t = new HashTable<Integer>();
Integer[] intArray = t.createArray(Integer.class, 4);
intArray[0] = 1; intArray[1] = 2;
intArray[2] = 3; intArray[3] = 4;

System.out.println(Arrays.toString(intArray));
> [1, 2, 3, 4]

4 Comments

This is a reflectively-created array unsafely cast to a generic type. Not sure if it will count as a generic array creation. At least it is not for me. For me the whole point is that there is no full generic type information at runtime, therefore it is not possible to instatiate a new T.
Although this solution requires casting and warning suppression it shows a good work-around. I think that all guys here gave useful answers. (T[])Array.newInstance() is like (T[])new Object[] and like (T[])new ArrayList<T>().toArray(). All these solution are "not clear" that was perfectly explained by @Amir Pashazadeh
@edalorzo you're right, I added a warning at the beginning of my answer
@Alex Would't (T[]) new Object[] end up causing a ClassCastException? Because arrays are reifiable, and an array of Object is not array of T and therefore this cast could never succeed, as far as I know. If so, this cannot be the same as the suggeste answer. Neither would succed the toArray() method because of the same reasons.
2

You could NOT create a T (in Java), but an T[] is internally the same as Object[].

public class HashTable<T> {

    private T[] array;

    @SuppressWarnings("unchecked")
    HashTable(int initSize) {
        this.array = (T[]) new Object[initSize];
    }
}

(Will compile, I checked)

Due to comments of newacct, it would be probably better just to use an Object[] and to cast the items to T.

public class HashTable<T> {

    private Object[] array;

    public HashTable(int initSize) {
        this.array = new Object[initSize];
    }

    public void put(String pKey, T pItem) {
       ...
       array[x] = pItem;
       ....
    }
    public T get(String pKey) {
       ...
       return (T) array[x];
    }
}

3 Comments

Yes, but you have to be careful because if you have a method that returns that array as T[] to the outside, it will crash and there won't be any warnings. e.g. public T[] toArray() { return array; }
@newacct: I checked, you are right. However, it is still wondering me. The cast in constructor will not throw an exception. And it is legal to put any type into an Object[]. I do not see the need to throw an exception in this case
Different array types are different classes at runtime, so if you create an Object[], you cannot cast it to a String[]. There is no real cast in the constructor, because T is erased within the scope of the class. Rather, every time someone gets something from the class of type T, the compiler will insert a cast there to the type they expect. e.g. when somebody calls HashTable<String> foo = ...; String bar = foo.get("baz"); becomes erased to HashTable foo = ...; String bar = (String)foo.get("baz"); That's why the exception occurs in the calling code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.