Question

Another one of those how do I do toArray() with no warnings questions, but it's different from most of the ones posted here.

How do I rewrite the method implementation (without changing the method signature) to make it compile without warning?

The apparent difficulty here is that the Class information for T is not available during runtime. However, the return type is an erased type during runtime too, so there's no really reason that this cannot be done. So, how do I do this if want to enforce compile-time type safety?

Thank you

<T> GenericClass<T>[] toGenericArray(List<GenericClass<T>> list) {
    return list.toArray(new GenericClass[0]);
}
Was it helpful?

Solution

You can't. Because Arrays are covariant, it is impossible to have compile time safety for an array that's holding a parameterized type. (unless you use < ? > which is legal.)

This will always be legal:

GenericClass<String>[] array = new GenericClass[1];
Object[] brokenArray = array;
brokenArray[0] = new GenericClass<Integer>();
String value = array[0].getGenericValue(); //kaboom

Compiler is unable to protect you from that, so it forces you to acknowledge/suppress that there's a warning.

OTHER TIPS

You can add an @SuppressWarnings("unchecked") annotation. This does not change the method signature and allows you to do "unsafe" things without generating a warning. Your code is genuinely safe, so it's OK to suppress the warning. Note that, per @Affe's answer, Bad Things may happen after you return, but you can certainly implement your method correctly.

The Java Collections framework does this kind of stuff internally so it's not just a hack. Well, it is a hack, but it's an OK hack. Well, it's not that OK, but it works. Kinda.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top