我有一个对象引用'inst',字段名'f',以及对另一个对象'v'的引用,该对象应该是对象'inst'上名称为n的字段的新值。
为了通过反射来实现这一点,我可以使用getDeclaredField()和"set"方法,但是,当字段"f"是某个祖先超类的字段时,或者当对象是匿名内部类的实例时,当字段属于封闭类时,我不确定该怎么做。
因此,在我看来,沿着父类(使用getSuperClass())和封闭类(使用getEnclosingClass(),有两条路径可以找到字段。
我的问题是,找到这个领域最优雅的方法是什么?
据我所知,有两种不雅的方法可以实现这一点:
- 使用静态递归方法创建一个助手类,该方法检查所有跨继承层次结构确定字段是否存在,并设置它-非常不雅并且可能存在漏洞
- 使用"bean"-传统的getters/ssetter并使用
getDeclaredMethod
,以便利用运行时多态性
这里有一个快速&关于2点的肮脏阐述:
package test;
import java.util.ArrayList;
import java.util.List;
public class MyClass {
boolean foo;
int bar;
public void setFoo(boolean value) {
foo = value;
}
public boolean getFoo() {
return foo;
}
public void setBar(int value) {
bar = value;
}
public int getBar() {
return bar;
}
@Override
public String toString() {
return String.format("Foo is %b and bar is %d", foo, bar);
}
public static String toGetterMethodName(String fieldName) {
// TODO no null nor length check here
return "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
}
public static String toSetterMethodName(String fieldName) {
// TODO no null nor length check here
return "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
}
public static void main(String[] args) {
// a bunch of reflection...
try {
List<MyClass> instances = new ArrayList<MyClass>();
instances.add((MyClass) Class.forName("test.MyClass$MyChildClass")
.newInstance());
instances.add((MyClass) Class.forName("test.MyClass")
.newInstance());
// default values
System.out.println(instances);
MyClass.class.getMethod(toSetterMethodName("foo"), boolean.class).invoke(instances.get(0), true);
MyClass.class.getMethod(toSetterMethodName("foo"), boolean.class).invoke(instances.get(1), true);
MyClass.class.getMethod(toSetterMethodName("bar"), int.class).invoke(instances.get(0), 42);
MyClass.class.getMethod(toSetterMethodName("bar"), int.class).invoke(instances.get(1), 42);
// values are now set
System.out.println(instances);
}
// TODO no specific Exception handling
catch (Throwable t) {
t.printStackTrace();
}
}
static class MyChildClass extends MyClass {
}
}
输出
[Foo is false and bar is 0, Foo is false and bar is 0]
[Foo is true and bar is 42, Foo is true and bar is 42]