java 反射 IllegalArgumentException 导致
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16042591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reflections IllegalArgumentException causes
提问by Aditya
UPDATE- To make the question clearer.
更新- 使问题更清楚。
What is the possible cause of getting a ClassCastException while calling a method via reflections?
通过反射调用方法时获得 ClassCastException 的可能原因是什么?
I got the following stacktrace as a part of my application while trying to invoke a method via reflections.
在尝试通过反射调用方法时,我将以下堆栈跟踪作为我的应用程序的一部分。
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)
I tried an example class and passed various arguments of different types to it, but i always get a this exception.
我尝试了一个示例类并将不同类型的各种参数传递给它,但我总是得到这个异常。
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)
UPDATE -Here is the sample code i wrote to try recreating the exception
更新 -这是我为尝试重新创建异常而编写的示例代码
Interface to create proxy class
创建代理类的接口
package my.tests;
public interface ReflectionsInterface {
public abstract void doSomething();
}
This is the test class
这是测试类
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;
}
}
}
I am unable to understand the when i would get argument type mismatchand the ClassCastExceptionwould be caused. I am not able to re-create the exception and would like to know why it comes. Any working code that re-created it, or a source code reference throwing this exception in this case will be good
我无法理解何时会出现参数类型不匹配以及会导致ClassCastException。 我无法重新创建异常并想知道它为什么会出现。重新创建它的任何工作代码,或在这种情况下抛出此异常的源代码参考都很好
I have gone through the Method.class javadocs and source code, i am not able to figure out why this error comes.
我已经浏览了 Method.class javadocs 和源代码,我无法弄清楚为什么会出现这个错误。
回答by johnchen902
I had recreated the ClassCastException
by modifing your example code: Invoke invokeMethod
with a correct argument 10000 times, and then invoke it with wrong a wrong one.
我ClassCastException
通过修改您的示例代码重新创建了:invokeMethod
使用正确的参数调用10000 次,然后使用错误的参数调用它。
The main
method in the Reflections
class
类中的main
方法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(), ReflectionsInterface.class, "doSomething");
}
The invokeMethod
method in the Reflections
class
类中的invokeMethod
方法Reflections
public static void invokeMethod(Object obj, Class<?> clazz,
String methodName, 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();
}
}
Stack Trace:
堆栈跟踪:
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)
My explanation of the ClassCastException
:
我的解释ClassCastException
:
When you invoke invokeMethod
for the first time, JVM use a slower route, which is easier for programmers to debug (so it's slower!), so it will show a more friendly argument type mismatch
message when you passes a bad argument.
当你invokeMethod
第一次调用时,JVM 使用较慢的路由,这对于程序员来说更容易调试(所以它更慢!),所以argument type mismatch
当你传递一个错误的参数时它会显示更友好的消息。
When you invoke invokeMethod
for a lot of times (16 times are enough in my tests), JVM generated a GeneratedMethodAccessor***
in runtime, which is faster, with less error checking. So it will show such an ugly java.lang.ClassCastException@603a3e21
message when you passes a bad argument.
当您invokeMethod
多次调用时(在我的测试中 16 次就足够了),JVM 会GeneratedMethodAccessor***
在运行时生成一个,速度更快,错误检查更少。所以java.lang.ClassCastException@603a3e21
当你传递一个错误的论点时,它会显示出如此丑陋的信息。
回答by Jon Skeet
Well this is the problem:
嗯,这就是问题所在:
reflections.invokeMethod("doInt", 1L);
You're calling doInt
, but you're passing a long
value. So reflection is trying to cast a Long
to an Integer
, which is invalid.
您正在调用doInt
,但您正在传递一个long
值。所以反射试图将 a 转换Long
为 an Integer
,这是无效的。
I suspect you meant:
我怀疑你的意思是:
reflections.invokeMethod("doLong", 1L);
回答by mki
I have a bit modify your code to reproduce this error :
我对您的代码进行了一些修改以重现此错误:
java.lang.IllegalArgumentException: argument type mismatch
Here is the interface
这是界面
public interface ReflectionsInterface
{
public abstract void doSomething1(Integer i);
public abstract void doSomething2(String s);
}
Add the method in class Reflections and EntityInvocationHandler in order to compile. Then add this method in your main(). Execute and I produce the error runtime.
在类 Reflections 和 EntityInvocationHandler 中添加该方法以进行编译。然后在你的 main() 中添加这个方法。执行,我产生错误运行时。
invokeMethod(reflectionsProxy, "doSomething1", "1");
I have tried to get un ClassCastException but I didn't succeed. It occurs probably in your original code because there are more objects and an invalid type is passed to the method. Add logs and try to debug to isolated the ClassCastException.
我试图得到 un ClassCastException 但我没有成功。它可能发生在您的原始代码中,因为有更多的对象并且将无效类型传递给该方法。添加日志并尝试调试以隔离 ClassCastException。