不修改底层对象的Java反射嵌套方法

不修改底层对象的Java反射嵌套方法,java,pointers,reflection,Java,Pointers,Reflection,我正在接受一系列方法,并希望将它们链接在一起,以修改我正在使用的对象 例如,我从 "getStuff().get(1).get(3).setMoreStuff().put(stuff,6)" 我将其拆分为一个名为methods的数组,并清理每个方法中的参数,然后尝试修改它 Object res = this; String[] methods = targetString.split("\\.(?=\\D)"); for (String m : methods){ List<O

我正在接受一系列方法,并希望将它们链接在一起,以修改我正在使用的对象

例如,我从

"getStuff().get(1).get(3).setMoreStuff().put(stuff,6)"
我将其拆分为一个名为methods的数组,并清理每个方法中的参数,然后尝试修改它

Object res = this;
String[] methods = targetString.split("\\.(?=\\D)");
for (String m : methods){

    List<Object> params = new ArrayList<Object>();
    List<Object> params = new ArrayList<Object>();

                    for (String p : m.split("\\(|,|\\)")) {
                        try {
                            if (p.indexOf(".") != -1){
                                double tempD = Double.parseDouble(p);
                                params.add(tempD);
                            } else {
                                int tempP = Integer.parseInt(p);
                                params.add(tempP);
                            }
                        } catch (Exception ex) { //not a number
                            params.add(p);
                        }
                    }
    switch (params.size()) {
        case 1:
            res = res.getClass().getMethod(
                            params.get(0)
                                   ).invoke(res);
            break;
        case 2:
            res = res.getClass().getMethod(
                            params.get(0),
                            params.get(1).getClass()
                                   ).invoke(res, params.get(1));
            break;
        case 3:
            res = res.getClass().getMethod(
                            params.get(0), 
                            params.get(1).getClass(),           
                            params.get(2).getClass()
                                   ).invoke(res, params.get(1), params.get(2));
                                break; 
    }
因为我需要对这个调用返回的对象调用相同的getMethod

澄清:

Object res = this;
创建指向此的“指针”。所以当我打电话的时候

res.getStuff().setStuff(foo)
res = res.getStuff();
res = res.setStuff();
这也将被修改

但是当我打电话的时候

res.getStuff().setStuff(foo)
res = res.getStuff();
res = res.setStuff();
就像我在循环中做的那样, 这不会修改此引用的基础对象吗

编辑:根据请求包含更多代码

编辑2:增加了另一个例子,以澄清我的问题


Edit3:尝试添加更多代码,如果不包含每个类,则添加工作程序有点困难

对象不会更改引用,其值会更改。因此,如果您将其称为.get(“some key”),您将获得与使用反射输入的值相同的值


对吗?

您的一般方法应该是好的(尽管您的参数转换方法有点难看)-可能是细节造成了问题。下面是一个简短但完整的程序,演示了调用方法,然后看到了不同之处:

import java.lang.reflect.*;

class Person {
    private String name = "default";

    public String getName() {
        return name;
    }

    // Obviously this would normally take a parameter
    public void setName() {
        name = "name has been set";
    }
}

class Test {

    private Person person = new Person();

    public Person getPerson() {
        return person;
    }

    // Note that we're only declaring throws Exception for convenience
    // here - diagnostic code only, *not* production code!
    public void callMethods(String... methodNames) throws Exception {
        Object res = this;
        for (String methodName : methodNames) {
            Method method = res.getClass().getMethod(methodName);
            res = method.invoke(res);
        }
    }

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        test.callMethods("getPerson", "setName");
        System.out.println(test.getPerson().getName());
    }
}

正如我所期望的,输出是“name has set”。所以,看看你是否可以一点一点地简化你的代码,删除额外的依赖项等等,直到你得到类似的简短但完整的东西,但这是行不通的。我怀疑你会在走的时候发现问题。

我看应该没问题。实际上,您根本没有复制对象。请展示一个简短但完整的程序来演示问题。(您可能希望将代码简化一点,例如,只调用一个方法,或者只支持无参数方法。)我又添加了几行代码。但它们似乎都不相关。困扰我的那一行是在我设置res=res.getClass().getMethod(…).invoke(…)的开关中,我没有要求“再多写几行代码”。我要求一个简短但完整的程序来演示这个问题——我们可以自己运行这个程序来帮助您诊断这个问题。请阅读抱歉@JonSkeet,我无意冒犯你。只是发现很难添加一个完整的程序,在没有其他类和基础设施的情况下编译和运行。是什么让它变得困难?它根本不需要“其他基础设施”。我会补充一个答案,明确我的意思。我不确定我是否明白你想说什么。我能够为数组中的每个方法调用每个get和put方法。在每一步中,我都可以看到变量res在变化,但我没有一个对象包含这些方法引起的所有变化。你是想告诉我,每次我在res上调用赋值运算符时,我都在创建一个新对象吗?谢谢Jon。经过几个小时的调试后,我发现我以这种方式调用的get方法之一并没有真正返回底层对象,而是使用new关键字返回了一个副本。谢谢你的帮助!