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 |