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?
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>
Since your method argument is a parameterized collection type, getGenericParameterTypes
returns a ParameterizedType
, not a Type
. To get the actual type, you need to first check whether each element of argTypes
is an instance of ParameterizedType
, and if it is call ParameterizedType.getActualTypeArguments()
.
Having said that, I can't tell what your code is trying to do. Your result object is still a List<Object>
, so you are still going to have to cast the elements to their correct type when you get them from the list. Casting the elements before storing them in the list doesn't accomplish anything.
Type[] argTypes = method.getParamterTypes()
I believe you are missing an "e" in your method call, should be getParameterTypes()