Reputation: 727
I have an object reference 'inst', field name 'f', and the reference to another object 'v' which should be the new value for the field with name n on object 'inst'.
In order to do this by reflection I can use getDeclaredField() and the 'set' method, however I am unsure of the best thing to do when field 'f' is a field of some ancestor superclass, or when the field belongs to an enclosing class when the object is an instance of an anonymous inner class.
Therefore it seems to me there are two paths to find the field along - parent superclasses (using getSuperClass()) and enclosing classes (using getEnclosingClass()).
My issue is what is the most elegant way to find the field?
Upvotes: 1
Views: 654
Reputation: 48404
There are two inelegant ways to achieve this, that I know of:
getDeclaredMethod
, in order to leverage the runtime polymorphism insteadHere's a quick & dirty elaboration on point 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 {
}
}
Output
[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]
Upvotes: 2