Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

surprising compilation error getting the array class of a class

Lately I've been doing a lot with reflection and implemented this little utility method. I was surprised to find that the first version does not compile, but the latter does.

Does not compile:

 public static <T> Class<T[]> getArrayClassOfType(Class<T> componentType) {
     return Array.newInstance(componentType, 0).getClass();
 }

Compiles and works just fine:

 public static <T> Class<T[]> getArrayClassOfType(Class<T> componentType) {
     Class c = Array.newInstance(componentType, 0).getClass();
     return c;
 }

Two questions: what's wrong with it? is there a better way of doing this?

Here's the compilation error from the first:

TypeUtils.java:[12,60] incompatible types: java.lang.Class<capture#1 of ? extends java.lang.Object> cannot be converted to java.lang.Class<T[]>
like image 501
RutledgePaulV Avatar asked Jan 04 '15 19:01

RutledgePaulV


1 Answers

The return type of getClass() is Class<?>.

In your example, you are assigning Class<?> to Class<T[]> (in the return statement), which is wrong, you need a cast.

This will compile fine:

@SuppressWarnings("unchecked") // added to suppress compiler warning
public static <T> Class<T[]> getArrayClassOfType(Class<T> componentType)
{
    return (Class<T[]>) Array.newInstance(componentType, 0).getClass();
}

With your second example, you use raw type Class, which works OK - casting raw type seems to be implicit. However, you will get a compiler warning, since this is a discouraged technique.

If you properly parametrize it as Class<?>, you will need the cast too.

like image 118
MightyPork Avatar answered Oct 03 '22 18:10

MightyPork