java – Reflections IllegalArgumentException原因
更新 – 使问题更清楚.
在通过反射调用方法时可能会导致ClassCastException异常? 在尝试通过反射调用方法时,我将以下堆栈跟踪作为我的应用程序的一部分. java.lang.IllegalArgumentException: java.lang.ClassCastException@21fea1fv at sun.reflect.GeneratedMethodAccessor332.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com..... (remaining is my method stack trace) 我尝试了一个示例类,并传递了不同类型的各种参数,但是我总是得到一个这个异常. java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) 更新 – 接口创建代理类 package my.tests; public interface ReflectionsInterface { public abstract void doSomething(); } 这是测试类 package my.tests; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Reflections implements ReflectionsInterface { public static void main(String[] args) { Reflections reflections = new Reflections(); ReflectionsInterface reflectionsProxy = reflections.createProxy(ReflectionsInterface.class); invokeMethod(reflectionsProxy,"doSomething",null); } public <T> T createProxy(Class<T> entityInterface) { EntityInvocationHandler eih = new EntityInvocationHandler(this); T cast = entityInterface.cast(Proxy.newProxyInstance( entityInterface.getClassLoader(),new Class[]{entityInterface},eih)); return cast; } public static void invokeMethod(Object obj,String methodName,Object... args) { Method[] methods = obj.getClass().getMethods(); try { for (Method method : methods) { if (method.getName().equals(methodName)) { method.invoke(obj,args); break; } } } catch (Exception e) { e.printStackTrace(); } } public void doSomething() { System.out.println("woo"); } private final static class EntityInvocationHandler implements InvocationHandler,ReflectionsInterface { private Reflections reflectionObj; public EntityInvocationHandler(Reflections reflectionObj) { super(); this.reflectionObj = reflectionObj; } @Override public void doSomething() { reflectionObj.doSomething(); } @Override public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { Object invoke = method.invoke(this,args); return invoke; } } } 我无法理解什么时候我会得到参数类型不匹配,并引起ClassCastException. 我经历了Method.class的javadocs和源代码,我无法弄清楚为什么会出现这个错误. 解决方法
我通过修改示例代码重新创建了ClassCastException:使用正确的参数调用invokeMethod 10000次,然后调用错误的一个.
在Reflections类中的主要方法 public static void main(String[] args) { Reflections reflections = new Reflections(); ReflectionsInterface reflectionsProxy = reflections .createProxy(ReflectionsInterface.class); for (int i = 0; i < 10000; i++) invokeMethod(reflectionsProxy,ReflectionsInterface.class,"doSomething"); invokeMethod(new Object(),"doSomething"); } Reflections类中的invokeMethod方法 public static void invokeMethod(Object obj,Class<?> clazz,Object... args) { Method[] methods = clazz.getMethods(); try { for (Method method : methods) { if (method.getName().equals(methodName)) { method.invoke(obj,args); break; } } } catch (Exception e) { e.printStackTrace(); } } 堆栈跟踪: java.lang.IllegalArgumentException: java.lang.ClassCastException@603a3e21 at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.twbbs.pccprogram.Reflections.invokeMethod(Reflections.java:33) at org.twbbs.pccprogram.Reflections.main(Reflections.java:16) 我对ClassCastException的解释: 当您第一次调用invokeMethod时,JVM使用较慢的路由,这对程序员来说更容易进行调试(因此它更慢!),因此当传递错误的参数时,它将显示更友好的参数类型不匹配消息. 当你调用invokeMethod很多次(在我的测试中有16次),JVM在运行时生成了一个GeneratedMethodAccessor ***,这样更快,错误检查更少.所以当你传递一个坏的参数时,它会显示一个这么丑的java.lang.ClassCastException@603a3e21消息. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |