使用Java Reflection时出现ClassCastException

时间:2018-05-30 16:59:04

标签: java reflection

我正在使用从骨架接收数据的存根:

MethodCallMessage reply = messageManager.wReceive();
        String returnString = reply.getParameter("result.string");
        int returnInt = Integer.parseInt(reply.getParameter("result.integer"));
        char returnChar = reply.getParameter("result.character").charAt(0);
        boolean returnBool = Boolean.valueOf(reply.getParameter("result.bool"));
        System.out.println("String return value in Invocation Handler: " + returnString);
        System.out.println("Int return value in Invocation Handler: " + returnInt);
        System.out.println("Char value in Invocation Handler: " + String.valueOf(returnChar));
        System.out.println("Bool value in Invocation Handler: " + String.valueOf(returnBool));

然后我尝试创建一个不同包中的类的实例:

Class c = Class.forName(method.getReturnType().getName());
c.newInstance();

我可以使用方法,所以我认为一切都很花哨:

Method[] methods = c.getDeclaredMethods();
        System.out.println("size: " + methods.length);
        for(Method method1: methods){
            System.out.println(method1.getName());
            if(method1.getReturnType().getSimpleName().equals("string")){
                System.out.println("heir");
                method1.invoke(c, returnString);
            }
            if(method1.getReturnType().getSimpleName().equals("int")){
                method1.invoke(c, returnInt);
            }
            if(method1.getReturnType().getSimpleName().equals("char")){
                method1.invoke(c, returnChar);
            }
            if(method1.getReturnType().getSimpleName().equals("boolean")){
                method1.invoke(c, returnBool);
            }

        }

并在最后我返回对象:

return c;

但后来我得到了:

java.lang.ClassCastException: java.lang.Class cannot be cast to be.kdg.distrib.testclasses.TestObject

包是我通过Class.forName()传递的。 为什么我可以进入方法和领域,但可以投射它?

修改

为了澄清,此代码是在StubInvocationHandler中编写的,旨在通过以下测试:

@Test
public void testWithObjectReturnValue() {
    testSkeleton.sendObjectReturnValue();
    TestInterface stub = (TestInterface) StubFactory.createStub(TestInterface.class, "127.0.0.1", port);
    TestObject test = stub.testMethod11();
    MethodCallMessage message = testSkeleton.getMessage();
    assertEquals("testMethod11", message.getMethodName());
    assertEquals(0, message.getParameters().size());
    assertEquals('r', test.getCharacter());
    assertEquals("bloop", test.getString());
    assertEquals(123, test.getInteger());
    assertTrue(test.isBool());
}

这是堆栈跟踪:

java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

1 个答案:

答案 0 :(得分:2)

不要使用原始类型!使用Class<?>代替Class

主要问题是您传入c作为调用方法的对象。 c的类型为Class,绝对不是您要调用的方法的类型:)

您似乎知道必须创建一个实例才能通过调用c.newInstance来调用方法,但是您忘记分配给变量:

Object instance = c.newInstance();

您应该传递instance,而不是c

另外,您确定返回c是否正确?在您的测试中,似乎testMethod11应该返回TestObject,这意味着应该重新调整instance