While answering to a question about that here: https://mcmap.net/q/1780157/-store-comparators-objects-in-array
I tried to do the following:
Comparator<String>[] comparators = new Comparator[] {...};
It works! But the following doesn't:
Comparator<String>[] comparators = new Comparator<String>[] {...};
On the related question, i made the assumption:
I guess it's because initially the array contract may be something like this:
If you create an array of type X, you will NEVER EVER be able to put anything in it that IS-NOT-AN X. If you try, you'll get an ArrayStoreException
Thus allowing arrays with generics creation would lead to a different rule like:
If you create an array of type
X<Y>
, you will NEVER EVER be able to put anything that IS-NOT-AN X. If you try, you'll get an ArrayStoreException. But you CAN add bothX<Y>
andX<Z>
objects because of type erasure!
But thinking about it, would it really be a problem to have:
Comparator<String>[] comparators = new Comparator<String>[] {...};
I don't really understand why it's not possible, since using such a thing would:
- Check the classes inserted at runtime
- Check the classes type inserted at compile time
Finally we can use an array with generic type reference and because of the impossibility to create an array with a generic type, i think many people do not even know it's possible.
I just wonder if someone knows the reason behind this choice?
It's a bit like forcing people to use List<String> = new ArrayList();
instead of using List<String> = new ArrayList<String>();
dimitrisli you gave a nice exemple from Joshua Bloch's famous book. As you/he explained it, it is dangerous to use both generic arrays + covariance and could lead to ClassCastException while we expect ArrayStoreException from an array with use of covariance.
But please notice the following is still legal and lead to the same:
List<String>[] stringLists = new List[1];
List<Integer> intList = Arrays.asList(42);
Object[] objects = stringLists;
objects[0] = intList;
String s = stringLists[0].get(0);
However it produces an unchecked cast warning at compile time, and as you mentionned, a ClassCastException at runtime.