Если у меня
public <T> doSomething(T[] array)
{
}
как я могу получить T.class
из array
?
Если я делаю array.getClass()
, который вместо меня получает T[].class
.
Если у меня
public <T> doSomething(T[] array)
{
}
как я могу получить T.class
из array
?
Если я делаю array.getClass()
, который вместо меня получает T[].class
.
Используйте это:
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
. Да, это законно и не генерирует предупреждения компилятора.)