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

11,261

Solution 1

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>

Solution 2

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.

Share:
11,261
java_enthu
Author by

java_enthu

Java, Hadoop, AWS, Kafka, Kubernetes, Docker, OpenShift and related technologies enthusiast.

Updated on June 16, 2022

Comments

  • java_enthu
    java_enthu almost 2 years

    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?