2

I'm having trouble figuring out what type parameter is expected at RHS of the following

ArrayList<Pair<ParseNode,ParseNode>>[] nodes = new ArrayList[indexes.length];

Why a copy of <Pair<ParseNode,ParseNode>> is not legitimate?

Tegiri Nenashi
  • 3,012
  • 2
  • 15
  • 19

3 Answers3

10

Arrays of concrete paramaterized types are inherently broken. Remember arrays are covariant and the array type check is a runtime operation. At runtime all the generics have been type erased, so the Array Store check can't tell <Pair<ParseNode, ParseNode>> from <Pair<BigInteger,IOException>>.

The fundamental contract of a generic is "I, the compiler, promise that if you write code that generates no warnings, you will never get a class cast exception at runtime."

Neither can the compiler guarantee to you that it will be able to give you a compile time error if something that is not an ArrayList<Pair<ParseNode,ParseNode>> is put into that array. Nor can the runtime system guarantee you will get an ArrayStoreException (like the Language Specification says it will) if you add the wrong type, rather than a ClassCastException later when you take it back out. (The second part is really why it's actually illegal rather than just a warning, it would result in an array that doesn't obey the language specification.)

So it doesn't let you declare them that way and forces you to acknowledge the 'unsafe' warning. That way it has said "I told you I can't guarantee there will not be any class cast exceptions as a result of using this array, it's on you to make sure you only put the right things in here."

Affe
  • 45,134
  • 11
  • 79
  • 81
6

Java not supports generic arrays. Arrays are covariant, generics are not. This means that if class A extends class B then A[] is also B[]. And code

A[] a = new A[10];
B[] b = a;

is legal.

But it is not same for generics. You could not assign Foo<T> to Foo<X> even if T extends X. And so elements of Foo<T>[] can't be guaranteed type safe.

EDIT Excuse me for just linking out, but I've found Java theory and practice: Generics gotchas article, that explains everything about arrays covariance better than I even would dream.

Mersenne
  • 2,099
  • 1
  • 14
  • 17
  • Indeed. And more information about that fact is here: http://stackoverflow.com/questions/529085/java-how-to-generic-array-creation – Mike Clark Mar 03 '12 at 00:12
  • I regret that I began answering this question. Understanding is good, but it worth nothing when you can't clearly explain that :) And now i see that is left unclear. – Mersenne Mar 03 '12 at 00:24
0

Don't use an array. Use another ArrayList.

ArrayList<List<Pair<ParseNode,ParseNode>>> listOfLists = new ArrayList<List<Pair<ParseNode,ParseNode>>>();

listOfLists.add(new ArrayList<<Pair<ParseNode,ParseNode>>());
Skip Head
  • 6,800
  • 1
  • 27
  • 34