0
class Generic<T> {}
Generic<Object>[] gib;
gib = new Generic<Object>[5]; // here is the line throwing Generic array creation error

I don't understand why this sample should be considered generic array creation, because the generic array creation I've seen so far is created in the form like Generic<T>[SIZE], with an unknown type parameter. But in this sample, I explicitly set the type parameter to Object, I guess my understanding of generic array must have some flaws, hope someone could help.

Alan Lian
  • 27
  • 6
  • In general generics and arrays don't mix well. Arrays are expected to enforce runtime checks like `Object[] arr = new String[2];` (this will be OK), `arr[1] = 1;` this will also compile but at runtime it will throw exception because `1` is not a `String`. This type checking can't be done for generics because at runtime they don't exist (compiler replaces `T` with `Object` - for backward compatibility with versions which didn't have generic types). So instead of arrays we are using types like `List`s, in your case `List> list = new ArrayList<>();`. – Pshemo Jul 01 '18 at 07:36
  • It is irrelevant if you yourself set `T` to `Object` - it still is part of generics mechanism and that type will be also erased to `Object` so at runtime JVM doesn't know what it was at first so compiler still complains about mixing arrays with generic type. Preferred solution is using lists instead of arrays. – Pshemo Jul 01 '18 at 07:47
  • @Pshemo Good illustration. I see that now my sample is still a generic array creation. – Alan Lian Jul 01 '18 at 12:54

1 Answers1

1

You can't do this because at runtime, the generic type parameters will be erased and you'd lose type safety.

Here's a code snippet that demonstrates this, taken from here

Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                            // but the runtime can't detect it.

"The runtime can't detect it" because the type parameters are gone at runtime. The runtime thinks ArrayList<String> and ArrayList<Integer> are the same thing - ArrayList. It doesn't matter what generic type parameter you put when you create the array.

Sweeper
  • 145,870
  • 17
  • 129
  • 225