繁体   English   中英

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

[英]Java - find field of object using reflection

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

为了通过反射做到这一点,我可以使用getDeclaredField()和'set'方法,但是我不确定当字段'f'是某些祖先超类的字段时,或者当该字段属于一个父类时,最好的做法当对象是匿名内部类的实例时,包含类。

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

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

我知道有两种巧妙的方法可以实现此目的:

  1. 使用静态递归方法创建一个帮助程序类,该方法检查整个继承层次结构中的所有字段是否存在并进行设置- 非常不雅致且可能存在错误
  2. 使用“ bean”常规的getter / setter并使用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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM