代码之家  ›  专栏  ›  技术社区  ›  Audiosleef

在使用Java反射时重新编译

  •  -2
  • Audiosleef  · 技术社区  · 6 年前

    我正在处理一个从骨架接收数据的存根:

    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
    

    这个包是我通过类传递的。 为什么我可以进入方法和领域,但可以投?

    编辑:

    为了澄清,这段代码是用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());
    }
    

    这里是StackTrace:

    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 回复  |  直到 6 年前
        1
  •  2
  •   Sweeper    6 年前

    不要使用原始类型!使用 Class<?> 而不是 Class !

    主要的问题是你进来了 c 作为调用方法的对象。 C 属于类型 等级 ,绝对不是要调用的方法声明的类型:)

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

    Object instance = c.newInstance();
    

    你应该通过 instance 不是 C .

    还有,你确定回来了吗 C 是正确的吗?从你的测试来看 testMethod11 应该返回 TestObject ,这意味着 实例 应该重新调整。