Arrays know their component type at runtime and every time you set a non-null reference on an array, it checks at runtime, that the object the reference points to is an instance of the array's component type; if it isn't, it's guaranteed to throw an ArrayStoreException
.
Object[] foo = new Integer[42];
foo[0] = "bar"; // throws ArrayStoreException -- "bar" is not an instance of Integer
However, it's not possible to check that an object is an instance of a parameterized type, since objects do not know their type arguments at runtime. It's only possible to check that an object is an instance of a reified type at runtime; and that's why array component types are only allowed to be reified types.
You can still create an array of the raw type and assign it to the type of array of the parameterized type, as you are doing:
private ArrayList<node>[] arr = new ArrayList[5];
Or you can create an array of the unbounded wildcard type (which is also reified) and then explicitly cast it to the type of array of the parameterized type:
private ArrayList<node>[] arr = (ArrayList<node>[])new ArrayList<?>[5];
In both cases there will be an unchecked warning. By giving you a warning, that means you take responsibility for bad things that might happen. For example:
Object[] foo = arr;
foo[0] = new ArrayList<String>(); // no ArrayStoreException -- it is an instance of ArrayList
// now you have an ArrayList<node>[] that contains an ArrayList<String>