簡體   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