Подтвердить что ты не робот

Java: получение класса компонентов массива

Если у меня

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

как я могу получить T.class из array?

Если я делаю array.getClass(), который вместо меня получает T[].class.

4b9b3361

Ответ 1

Тип компонента

Используйте это:

array.getClass().getComponentType()

Возвращает Class, представляющий компонентный тип массива. Если это класс не представляет собой массив класс этот метод возвращает null.

Справка:


Безопасное/небезопасное литье

Есть ли способ, который я могу применить к классу из класса, возвращаемого getComponentType() без получения предупреждение компилятора?

возьмите этот метод:

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();
}

Здесь сгенерированный байт-код:

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

Как вы можете видеть, тип параметра стирается до Object [], поэтому компилятор не знает, что такое T. Да, компилятор мог бы использовать array.getClass().getComponentType(), но это иногда терпит неудачу, потому что вы можете делать такие вещи:

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

(В этом случае array.getClass().getComponentType() возвращает String.class, но T обозначает Integer. Да, это законно и не генерирует предупреждения компилятора.)