0

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

例如我从

"getStuff().get(1).get(3).setMoreStuff().put(stuff,6)"

我将它拆分为一个称为方法的数组,并清理每个方法中的参数,然后尝试对其进行修改。

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; 
    }

最后我注意到 res 已经按照我期望的方式进行了修改。所有的 getter 和 setter 都被正确调用。但是当然,“this”所指的底层对象并没有改变!

我想我只是在调用我在第一行制作的副本的 getter 和 setter!

现在我不能只使用

this.getClass().getMethod(...).invoke(...) 

因为我需要在此调用返回的对象上调用相同的 getMethod。

澄清:

Object res = this;

为此创建一个“指针”。所以当我打电话

res.getStuff().setStuff(foo)

这也将被修改。

但似乎当我打电话时

res = res.getStuff();
res = res.setStuff();

就像我在循环中所做的那样,这不会修改它所指的基础对象吗?

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

Edit2:添加了另一个示例,以澄清我的问题。

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

4

2 回答 2

2

Your general approach should be fine (although your approach to parameter conversion is somewhat ugly) - it's the specifics that are presumably causing you problems. Here's a short but complete program demonstrating calling methods and then seeing the difference afterwards:

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());
    }
}

The output is "name has been set" just as I'd expect. So see if you can simplify your code bit by bit, removing extra dependencies etc until you've got something similarly short but complete, but which doesn't work. I suspect you'll actually find the problem as you go.

于 2013-10-01T06:36:48.223 回答
0

对象不会改变引用,它的 VALUE 会改变。因此,如果您调用 this.get("some key"),您将获得与使用反射相同的值。

正确的?

于 2013-10-01T05:43:05.123 回答