java: getting the class of the components of an array

21,714

Solution 1

Component Type

Use this:

array.getClass().getComponentType()

Returns the Class representing the component type of an array. If this class does not represent an array class this method returns null.

Reference:


Safe / Unsafe casting

Is there a way I can cast to Class from Class returned by getComponentType() without getting a compiler warning?

take this method:

public <T> void doSomething(final T[] array) throws Exception{
    final Class<? extends Object[]> arrayClass = array.getClass();
    final Class<?> componentType = arrayClass.getComponentType();
    final T newInstance = (T) componentType.newInstance();
}

Here's the generated byte code:

public void doSomething(java.lang.Object[] array) throws java.lang.Exception;
     0  aload_1 [array]
     1  invokevirtual java.lang.Object.getClass() : java.lang.Class [21]
     4  astore_2 [arrayClass]
     5  aload_2 [arrayClass]
     6  invokevirtual java.lang.Class.getComponentType() : java.lang.Class [25]
     9  astore_3 [componentType]
    10  aload_3 [componentType]
    11  invokevirtual java.lang.Class.newInstance() : java.lang.Object [30]
    14  astore 4 [newInstance]
    16  return

As you can see, the parameter type is erased to Object[], so the compiler has no way to know what T is. Yes, the compiler could use array.getClass().getComponentType(), but that would sometimes fail miserably because you can do stuff like this:

Object[] arr = new String[] { "a", "b", "c" };
Integer[] integerArray = (Integer[]) arr;
doSomething(integerArray);

(In this case array.getClass().getComponentType() returns String.class, but T stands for Integer. Yes, this is legal and does not generate compiler warnings.)

Solution 2

If you want to do this for multi-dimensional arrays the following recursive code will work

    Class<?> getArrayType(Object array) {
        Object element = Array.get(array, 0);
        if (element.getClass().isArray()) {
            return getArrayType(element);
        } else {
            return array.getClass().getComponentType();
        }
    }

Share:
21,714
Jason S
Author by

Jason S

Updated on March 09, 2020

Comments

  • Jason S
    Jason S about 4 years

    If I have

    public <T> doSomething(T[] array)
    {
    }
    

    how can I get T.class from array?

    If I do array.getClass() that gets me T[].class instead.