Java反射调用方法报String转Object数组ClassCastException原因求解
Java反射Method.invoke第三种写法报错原因分析
这个异常是Java可变参数的编译期类型推导和泛型擦除共同作用导致的,具体逻辑如下:
首先明确两个核心方法的签名:
Method.invoke的方法签名为public Object invoke(Object obj, Object... args),第二个参数是可变参数,本质是Object[]类型。Gson.fromJson的方法签名为<T> T fromJson(String json, Type typeOfT),返回值是泛型类型,编译阶段会根据上下文做类型推导。
三种写法的运行逻辑差异
- 第一种写法(正常运行):你将
fromJson的返回值先赋值给了Object类型的input变量,调用invoke时,编译器会把单个Object类型的参数自动封装为Object[]数组的第一个元素,实际传入的参数是new Object[]{input},和目标方法getName的单个String参数匹配,运行正常。 - 第二种写法(正常运行):你给
fromJson指定了String.class作为类型,返回值明确是String类型,调用invoke时,编译器同样会把这个String对象自动封装为Object[]数组的第一个元素,参数匹配,运行正常。 - 第三种写法(运行报错):你直接把
fromJson的泛型返回值作为invoke的第二个参数,此时编译器的类型推导会优先匹配invoke的Object[]形参,直接把fromJson返回的泛型值当成整个Object[]数组传入。而你当前场景下genericParameterType是String类型,fromJson返回的是String对象,运行时JVM会尝试将String对象强转为Object[]类型,就抛出了对应的类转换异常,[Ljava.lang.Object;就是JVM中Object[]类的全限定名表示。
修复方案
如果要让第三种写法正常运行,只需要手动告诉编译器不要把返回值当成数组,两种写法可选:
// 方法1:强制转为Object类型,触发编译器自动封装数组 method.invoke(newInstance, (Object) new Gson().fromJson(jsonParams, genericParameterType)); // 方法2:手动封装为Object数组 method.invoke(newInstance, new Object[]{new Gson().fromJson(jsonParams, genericParameterType)});
内容的提问来源于stack exchange,提问作者Levin
相关产品推荐
相关产品推荐

