通过反射调用嵌套的deepobject方法

Invoke nested deepobject method via reflection

是否可以使用反射从真实对象调用嵌套对象内部的嵌套方法? 像这样

val fieldDefinition = chatClient.javaClass.getDeclaredField("class1")
  .type.getDeclaredField("class2").type.getDeclaredField("class3")

我拥有的真实对象是 chatClient,我想调用 class3 的方法,我无法直接获取该方法,只能通过 class1 路径。

是的,你必须边走边获取对象。

val class1 = chatClient.javaClass.kotlin.memberProperties.first { it.name == "class1" }.get(chatClient)!!
val class2 = class1.javaClass.kotlin.memberProperties.first { it.name == "class2" }.get(class1)!!
val class3 = class2.javaClass.kotlin.memberProperties.first { it.name == "class3" }.get(class2)!!
(class3 as ObjectType).method()

您不能通过使用 java 反射访问字段来做到这一点,因为这些字段是 private。您可以使用 java 反射并访问自动生成的 getter getClass1getClass2 等,或者使用 k-reflect.

使用 java 反射的示例:

val class1 = chatClient.javaClass.getMethod("getClass1").invoke(chatClient)
val class2 = class1.javaClass.getMethod("getClass2").invoke(class1)
val class3 = class2.javaClass.getMethod("getClass3").invoke(class2)

(class3 as ObjectType).method()

我试过了,很有效,有没有更好的解决方案?

   val fieldDefinition1 = chatClient.javaClass.getDeclaredField("class1")
    fieldDefinition1.isAccessible = true
    val fieldValue1 = fieldDefinition1.get(chatClient)

    val fieldDefinition2 = fieldDefinition1.type.getDeclaredField("class2")
    fieldDefinition2.isAccessible = true
    val fieldValue2 = fieldDefinition2.get(fieldValue1)


    val fieldDefinition3 =  fieldDefinition2.type.getDeclaredField("class3")
    fieldDefinition3.isAccessible = true
    val fieldValue3 = fieldDefinition3.get(fieldValue2)

    val myMethod = fieldValue3.javaClass.getDeclaredMethod("methodName")
    myMethod.isAccessible  = true
    myMethod.invoke(fieldValue3)

您可以在 for 循环内的函数中获取嵌套字段的逻辑,这样就可以避免代码重复。

java中的完整代码示例:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Class1 {
    Class2 class2 = new Class2();

}
class Class2 {
    Class3 class3 = new Class3();
}
class Class3 {
    Class4 class4 = new Class4();
}
class Class4 {

    public void display(){
        System.out.println("Hello World");
    }

}


public class Test {

    static Object getFieldValue(String fieldPath ,Object object) throws NoSuchFieldException, IllegalAccessException {
        String[] pathList = fieldPath.split("\.");
        for(String path : pathList){
            Field field = object.getClass().getDeclaredField(path);
            field.setAccessible(true);
            object = field.get(object);
        }
        return object;
    }

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class1 class1Object = new Class1();
        Object object = getFieldValue("class2.class3.class4", class1Object);

        Method method = object.getClass().getMethod("display");
        method.invoke(object);

    }
}

这里fieldPath in getFieldValue表示嵌套字段对象的路径。