ClassCastException While casting List<String> to Class<?>
Asked Answered
P

3

6

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?

Pneumato answered 8/7, 2011 at 11:44 Comment(5)
so, what is the type of argTypes[i]?Colorcast
@jtahlorn: // argTypes[1] =java.util.List<java.lang.String> fails.Pneumato
no, i mean what is the type of the actual value, which is failing the cast?Colorcast
actual value is of type String. ("aaa")Pneumato
nevermind, i realized that it should be a ParameterizedType, which @Indolon already answered below.Colorcast
S
9

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>
Slipcase answered 8/7, 2011 at 12:21 Comment(0)
I
1

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.

Intelligencer answered 8/7, 2011 at 12:42 Comment(0)
C
0
Type[] argTypes = method.getParamterTypes()

I believe you are missing an "e" in your method call, should be getParameterTypes()

Caseous answered 8/7, 2011 at 11:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.