ClassCastException При приведении списка <String>к классу - PullRequest
4 голосов
/ 08 июля 2011

У меня есть метод, у которого есть список входов и каждое входное значение, которое я должен привести к необходимому типу.(На самом деле этот список имеет значения параметров в «некоторой» форме, которую я должен преобразовать в требуемый тип, обязательный тип - это тип, который требует метод, это для вызова API через отражение)

Я написалкод, подобный следующему:

Type[] argTypes = method.getGenericParameterTypes();
List<Object> acutalValues = // List of actual values from method input.
// Resultant list of arguments which will holds casted values.
List<Object> arguments = new ArrayList<Object>(argTypes.length);

for (int i = 0; i < argTypes.length; i++) {
 Class<?> requiredClassTYpe = (Class<?>) argTypes[i]; // argTypes[1] =java.util.List<java.lang.String> fails..
 // cast the actual value to the required type. Required type is requiredClassType
 arguments.add(castToRequiredType(requiredClassTYpe, actualValues.get(i)));
 }

Сообщение об исключении выглядит следующим образом:

ClassCastException: Cannot cast sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl (id=77) to java.lang.Class

Теперь, если я изменю первую строку на

Type[] argTypes = method.getParameterTypes()

, тогда оно пропускает любуюидея, почему это может происходить так?

Ответы [ 3 ]

8 голосов
/ 08 июля 2011

Потому что, как указано в method.getGenericParameterTypes() JavaDoc, оно:

возвращает массив Type объектов, которые представляют формальные типы параметров

...

Если формальный тип параметра является параметризованным типом, возвращаемый для него объект Type должен точно отражать фактические параметры типа, используемые в исходном коде.

Таким образом, если объявление вашего метода выглядит следующим образом:

public void myMethod(String string, List<String> list) { ... }

argTypes[0] будет содержать экземпляр Class (то есть Class<? extends String>), но argTypes[1] будет содержать экземпляр java.lang.reflect.ParameterizedType.Вы можете получить информацию о фактических аргументах типа ParameterizedType, используя метод getActualTypeArguments().Пример для описанного выше случая:

Type[] listTypeArgs = ((ParameterizedType) argTypes[1]).getActualTypeArguments()

// listTypeArgs.length == 1 as List<String> have one type argument
// listTypeArgs[0] now contains instance of Class<? extends String>
1 голос
/ 08 июля 2011

Поскольку аргумент вашего метода является параметризованным типом коллекции, getGenericParameterTypes возвращает ParameterizedType, а не Type.Чтобы получить фактический тип, вам нужно сначала проверить, является ли каждый элемент argTypes экземпляром ParameterizedType, и если это вызов ParameterizedType.getActualTypeArguments().

Сказав это, я не могу сказать,что ваш код пытается сделать.Ваш результирующий объект по-прежнему List<Object>, поэтому вам все равно придется приводить элементы к их правильному типу, когда вы получаете их из списка.Приведение элементов перед сохранением их в списке ничего не дает.

0 голосов
/ 08 июля 2011
Type[] argTypes = method.getParamterTypes()

Я полагаю, что в вызове метода отсутствует "e", должно быть getParameterTypes()

...