Firstly new to Generics. Now question - In the HashMap.java I see the following -
transient Entry[] table;
which is initiated in constructor as
table = new Entry[capacity];
Why was this not declared with type parameters ?
Or
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
Why was Entry in the for loop declared with type parameters?
Is there a deep concept or just an affordable inconsistency ?
That's because creating an array of concrete parameterized type is not type safe, and that is why that's not allowed at all.
If you try code something like this, you would get a compiler error:
List<String>[] arr = new ArrayList<String>[10]; // Compiler error: Generic Array creation
The issue is that generic types are non-reifiable - their type information is not available at runtime. Meanwhile, arrays use type information that is available at runtime to do an ArrayStoreCheck
to see if an element inserted into an array is compatible with the array's type. So, if you mix up arrays and generics, then you might end up having surprising behaviour at runtime.
For example, consider the following code:
List<String>[] arr = new ArrayList<String>[10]; // Suppose this was valid
Object[] objArr = arr; // This is valid assignment. A `List[]` is an `Object[]`
objArr[0] = new ArrayList<Integer>(); // There you go. A disaster waiting at runtime.
String str = arr[0].get(0); // Assigned an `Integer` to a `String`. ClassCastException
So, had the 1st assignment compiled, the 4th assignment, which looks fine to the compiler, would have throw a ClassCastException
at runtime.
However, you can create an array of raw types - ArrayList
, or unbounded wildcard parameterized type - ArrayList<?>
, as both of them are fully reifiable types. So the following array creations are valid:
List[] arr = new ArrayList[10];
List<?>[] arr2 = new ArrayList<?>[10];
Since there is no type information associated with raw types or unbounded wildcard types, there is nothing to lose at runtime. And hence those types are reifiable, they are an eligible component type of an array. That is why Entry[]
is used instead of Entry<K, V>[]
.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With