我正在接受一系列方法,我想将它们链接在一起以修改我正在使用的对象。
例如我从
开始"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();
就像我在循环中所做的那样, this 不会修改 this 引用的底层对象?
编辑:根据请求包含更多代码。
Edit2:添加了另一个示例,以澄清我的问题。
Edit3:尝试添加更多代码,在不包含每个类的情况下添加工作程序有点困难
最佳答案
您的一般方法应该没问题(尽管您的参数转换方法有点难看) - 可能是细节导致了您的问题。这是一个简短但完整的程序,演示了调用方法,然后查看差异:
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());
}
}
正如我所期望的,输出是“名称已设置”。因此,看看是否可以一点一点地简化代码,删除额外的依赖项等,直到得到类似的简短但完整的代码,但这是行不通的。我怀疑您实际上会发现问题。
关于Java反射嵌套方法不修改底层对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19108691/