ClassCastException将List <string>转换为Class <! - ? - > </string>

时间:2011-07-08 11:44:02

标签: java list generics reflection classcastexception

我有一个方法,它有一个输入列表和每个输入值,我必须将其转换为所需的类型。 (实际上这个列表有“some”形式的参数值,我应该转换成所需的类型,所需的类型是方法所需的类型,这是通过反射调用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 个答案:

答案 0 :(得分:8)

因为如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()的实际类型参数的信息。上述案例I的示例:

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 :(得分:1)

由于您的方法参数是参数化集合类型,getGenericParameterTypes会返回ParameterizedType,而不是Type。要获取实际类型,您需要先检查argTypes的每个元素是ParameterizedType的实例,还是调用ParameterizedType.getActualTypeArguments()

话虽如此,我无法分辨你的代码试图做什么。您的结果对象仍然是List<Object>,因此当您从列表中获取元素时,您仍然必须将元素强制转换为正确的类型。在将元素存储到列表中之前强制转换元素并不能完成任何事情。

答案 2 :(得分:0)

Type[] argTypes = method.getParamterTypes()

我相信你在方法调用中缺少“e”,应该是getParameterTypes()