Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException While casting List<String> to Class<?>

I have a method which has a list of inputs and each input value I have to cast it to required type. (Actually this list has values of parameters in "some" form which I am supposed to converted into required type, the required type is the type which method requires, this is for api invocation through reflection)

I have written code like this:

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

The exception message is like this :

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

Now if I change the first line to

Type[] argTypes = method.getParameterTypes()

Then it passes any idea why it might be happening like this?

like image 969
java_enthu Avatar asked Jan 20 '23 06:01

java_enthu


1 Answers

Because as stated in method.getGenericParameterTypes() JavaDoc it:

returns an array of Type objects that represent the formal parameter types

...

If a formal parameter type is a parameterized type, the Type object returned for it must accurately reflect the actual type parameters used in the source code.

Thus if your method declaration looks like:

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

argTypes[0] will contain instance of Class (i.e. Class<? extends String>), but argTypes[1] will contain instance of java.lang.reflect.ParameterizedType. You can get information about actual type arguments of ParameterizedType using getActualTypeArguments() method. Example for case I described above:

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>
like image 67
Idolon Avatar answered Jan 30 '23 22:01

Idolon