|
From: Peter C. <cen...@ri...> - 2003-06-08 20:34:03
|
One of the greatest frustrations of GJ/JSR14 generics is the inability
to build new arrays of an appropriate type. It is a simple matter to
create a new generic collection, but the special nature of arrays
requires runtime type information that is not available when
implementing generics with erasure.
ArrayList<T> arrayList = new ArrayList<T>(); // Works fine.
T[] array = new T[5]; // Problematic.
I just discovered that Java 1.3 includes reflection support for
building correctly-typed arrays at runtime. Using this support, it is
possible to perform the command above, although in a roundabout,
un-type-checked way. This support could be very useful for designing
clean generic interfaces in parts of DrJava which make use of arrays.
Here's a trivial usage example:
import java.lang.reflect.*;
class RuntimeTyper {
<T> T[] makeTypedArray(T thing, int size) {
return (T[]) Array.newInstance(thing.getClass(), size);
}
}
Also keep in mind the typed toArray method in the Collection interface:
Object[] toArray(Object[] a);
Using these two capabilities together, we can get statically type-safe
arrays from generic Collections (assuming that the Collection is
non-empty):
<T> T[] getArray(Collection<T> stuff) {
Iterator iter = stuff.iterator();
if (iter.hasNext()) {
T[] array = (T[]) Array.newInstance(iter.next().getClass(), 0);
return stuff.toArray(array);
}
else {
// TODO: Perhaps some clever person could figure out how to
handle this case.
throw new IllegalStateException("Cannot make typed array from
empty Collection!");
}
}
--
Peter
|