views:

222

answers:

2

Hi all,

I have a dumb silly question, but sometimes you have to ask them anyways.

I got an Object[] instance in my left hand (it comes from non-generic swing) and a method that accepts a let's say Integer[] as its argument (in my case it's actually a vararg) in my right hand. I'm sure of the content of the array (or I'm ready to pay the price if I'm wrong).

So basically I wrote that :

private static <U, T extends U> T[] cast(final U[] input, final Class<T> newType) {
    //noinspection unchecked
    final T[] result = (T[]) Array.newInstance(newType, input.length);
    System.arraycopy(input, 0, result, 0, input.length);
    return result;
}

can you remove the unchecked warning, without unplugging it ?

why haven't Array.newInstance() been genericized ?

A: 

Short way: Put this above the method to suppress the warning:

@SuppressWarnings("unchecked")

Long way: Loop through and cast each element in turn:

Object[] a = new Object[1];
Integer b=1;
a[0]=b;
Integer[] c = new Integer[a.length];
for(int i = 0; i < a.length; i++)
{
    c[i] = (Integer) a[i];
}
Supertux
this is not exactly the answer I wanted to get I think.Moreover, in my real code, it's a //noinspection unchecked that lie directly over the statement.
nraynaud
+1. I'm not sure what "//noinspection" is (some IDEA-specific stuff?), but `@SuppressWarnings("unchecked")` is the correct way to suppress the unchecked warning. Java arrays are not genericized; you won't be able to do this any other way.
ChssPly76
maybe somebody has found a fonction that would simply push the warning into the JDK ? I can't find any good reason to have Array.newInstance() typed the way it is instead of <T> T[]newInstance(Class<T> elemType, int lenght).
nraynaud
+2  A: 

why haven't Array.newInstance() been genericized ?

It may be related to generics only being implemented for reference types. Array.newInstance( int.class, 42 ) is perfectly legal, Class<int> is not. With that limitation, there wasn't a backwards compatible way of making it type generic.

The java.util.Arrays class works round this by providing multiple overloads for each primitive type. So this works:

private static <U, T extends U> T[] cast ( final U[] input, final T[]  prototype ) {
    final T[] result = Arrays.copyOf ( prototype, input.length );
    System.arraycopy(input, 0, result, 0, input.length);
    return result;
}

If you don't mind passing in an empty array instead of the class object, it avoids the cast.

Pete Kirkham
your primitive types remark is a good one I think ! I haven't though about.
nraynaud