What's the explanation for the following:
public class GenericsTest {
//statement 1
public ArrayList<Integer>[] lists;
public GenericsTest()
{
//statement 2
lists = new ArrayList<Integer>[4];
}
}
The compiler accepts statement 1. Statement 2 is flagged by the compiler for "generic array creation".
A good explanation I've seen regarding disallowing generic arrays is this one, arguing that since arrays are covariant and generics are not you could subvert the generic typing if you allowed generic arrays.
Leaving aside the argument over whether the language should go to the extreme lengths of creating this kind of complicated inconsistency in the treatment of generics to keep you from shooting yourself no matter how hard you try (and if anyone knows of any good discussions on the relative merits/demerits of the issue please post, I'd be interested to see the arguments), why should statement (1) be allowed if (2) isn't?
There seems to be obscure cases where you could inadvertently cause a ClassCastException as explained here
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf (section 7.3)
an intersting discussion on this topic could be found here
http://courses.csail.mit.edu/6.170/old-www/2006-Spring/forum/index.php%3Ftopic=324.msg1131.html
It's because you can't create, but you can use them:
public class GenericsTest {
//statement 1
public ArrayList<Integer>[] lists;
public GenericsTest()
{
//statement 2
lists = new ArrayList[4];
//statement 3
lists[0].add(new Integer(0));
//statement 4
lists[0].add(new String(""));
}
}
Statement 3 is possible, statement 4 will lead to a compiler error.
So the actual question is: Why is there no error for declaring a generic array? ?
You will always get an error at the point you do something erroneous. Adding an error where there isn't technically a problem just adds to a clutter (although an editor might want to point that out to you).
In some circumstances you may want to bend the rules a bit with an unchecked cast. There's no need to force the code to be littered with more warning suppressions than necessary (other than to point out the folly).
In this case, I would avoid using arrays for just this reason. The declaration of "lists" in your original code could be
List<List<Integer>> lists = new ArrayList<List<Integer>>(4);
for(int i = 0; i < 4; i++) lists.add(null); // or add an empty ArrayList<Integer>
(you should use the interface rather than the implementation in variable declarations)
Instead of array [] syntax, you would use get() or set(). Other than that, it's equivalent.