Re: generic arrays
On Jan 2, 1:44 am, Owen Jacobson <angrybald...@gmail.com> wrote:
Roedy: have you thought about cloning the array you're passed and then
blanking it? You might also want to look at the source for
ArrayList.toArray(Object[]), which uses some reflective monkeying to
create an array "sufficiently large" and of the same element type as
the passed array, if the passed array is not large enough to hold the
list.
Excuse the self-followup, here.
You cannot completely avoid casts, but you can use casts that are
verifiably correct. Consider:
String[] args = new String[0]; // No element to query.
Class<? extends String[]> c = args.getClass ();
Class<?> elt = c.getComponentType ();
We know from reading the code that elt is really String.class (which
is of type Class<String>), but the depicted bounds are the most strict
bounds available without casts through the Reflection API. It gets
better.
Object newArr = java.lang.reflect.Array.newInstance (elt, 8);
newArr is actually a String[], which we can verify by inspection or by
reflection, and you can cast the object to String[] and use it as one
from there on.
The same is true if we replace String throughout with T, which is a
generic type in this scope.
Part of the problem is that there is no type relationship between
String[] and String that can be expressed using generics type
constraints.
For completeness, here is a tested class which, given an array,
creates another array of the same element type and returns it as a T[]
rather than an Object[].
package com.unreasonent;
import java.lang.reflect.Array;
public class Arrays {
private Arrays () {
assert (false);
}
public static <T> Class<?> getElementClass (T[] array) {
return array.getClass ().getComponentType ();
}
@SuppressWarnings("unchecked")
public static <T> T[] createArrayLike (T[] original, int length) {
Class<?> eltType = getElementClass (original);
return (T[]) Array.newInstance (eltType, length);
}
}
-o