THashMap declares the _values array as V[]
using the type parameter V for the value type. It is initialized with in rehash() and setUp() with (V[]) new Object[]
. In the normal case where THashMap is used as THashMap<Foo,Bar> myMap;
the _values array is erased to Object[]
. But when THashMap is extended as in class TMyHashMap extends THashMap<Foo,Bar> { ... }; TMyHashMap myMap;
it will be erased to Bar[]
. So in the former case, the compile-time array type is Object[]
whereas in the latter case it is Bar[]
. At runtime, the array value will be Object[]
in both cases. This will cause problems in array assignments in the TMyHashMap subclass because the compiler assumes a Bar[]
array and _values[index] = new Bar()
fails with java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [com.foo.LBar
.
One solution would be declaring _values as Object[]
and adding casts to V where needed. This is what java.lang.ArrayList does. Another solution would be to extract the array allocation into a method and allow subclasses to override it:
protected V[] allocate( int size ) { return (V[]) new Object[ size ]; } ... _values = allocate();
And in TMyHashMap:
@Override protected Bar[] allocate( int size ) { return new Bar[ size ]; }
This might also reduce the number of necessary @SuppressWarnings("unchecked")
annotations.
BitBucket issue: https://bitbucket.org/robeden/trove/issue/7/