Java-使用反射查找对象的字段



我有一个对象引用'inst',字段名'f',以及对另一个对象'v'的引用,该对象应该是对象'inst'上名称为n的字段的新值。

为了通过反射来实现这一点,我可以使用getDeclaredField()和"set"方法,但是,当字段"f"是某个祖先超类的字段时,或者当对象是匿名内部类的实例时,当字段属于封闭类时,我不确定该怎么做。

因此,在我看来,沿着父类(使用getSuperClass())和封闭类(使用getEnclosingClass(),有两条路径可以找到字段。

我的问题是,找到这个领域最优雅的方法是什么?

据我所知,有两种不雅的方法可以实现这一点:

  1. 使用静态递归方法创建一个助手类,该方法检查所有跨继承层次结构确定字段是否存在,并设置它-非常不雅并且可能存在漏洞
  2. 使用"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]

相关内容

  • 没有找到相关文章

最新更新