web-dev-qa-db-ja.com

Javaクラスのすべてのフィールドをループする

JavaのクラスにはFieldsの数があるクラスがあります。

私はすべてのフィールドをループし、ヌルであるフィールドに対して何かをしたいと思います。

たとえば、クラスが次の場合:

public class ClassWithStuff {
    public int inty;
    public stringy;         
    public Stuff;
    //many more fields
}

別の場所で、ClassWithStuffオブジェクトを作成し、クラスのすべてのフィールドにアクセスしたいと思います。このようなもの:

for (int i = 0; i < ClassWithStuff.getFields().size(); i++) {
      //do stuff with each one
}

これを達成する方法はありますか?

24
CodyBugstein

[クラス]でgetDeclaredFieldsを使用します

ClasWithStuff myStuff = new ClassWithStuff();
Field[] fields = myStuff.getClass().getDeclaredFields();
for(Field f : fields){
   Class t = f.getType();
   Object v = f.get(myStuff);
   if(t == boolean.class && Boolean.FALSE.equals(v)) 
     // found default value
   else if(t.isPrimitive() && ((Number) v).doubleValue() == 0)
     // found default value
   else if(!t.isPrimitive() && v == null)
     // found default value
}

http://docs.Oracle.com/javase/1.5.0/docs/api/Java/lang/Class.html

20

はい、反射で。

Classオブジェクトを使用して、 getFields() メソッドでFieldオブジェクトにアクセスします。

_Field[] fields = ClassWithStuff.class.getFields();
_

次に、フィールドをループします。これは、宣言したすべてのフィールドがpublicであるため機能します。そうでない場合は、 getDeclaredFields() を使用します。これは、クラスで直接宣言されているすべてのFieldspublicにアクセスします。

8
rgettman

探しているのは reflection です。 Reflectionを使用すると、独自のクラスまたは別のクラスを調べて、それが何で構成されているかを確認できます。 Javaにはリフレクションが組み込まれているため、すぐに使用できます。その後、次のようなことができます-

for(Field f : ClasWithStuff.getFields()){
    System.out.println(f.getName());//or do other stuff with it
}

これを使用して、メソッドやコンストラクターなどを取得し、同様の優れた機能を実行することもできます。

2
David Grinberg

Java 8+ライブラリを使用したソリューション durian およびStream

ユーティリティメソッド FieldsAndGetters.fields(Object obj)

指定されたオブジェクトのすべてのパブリックフィールドとその値のストリームを返します。

これらはすべてパブリックであるため、ClassWithStuffのフィールドを検索します。

(少し変更した)ClassWithStuffで使用する方法を見てみましょう:

public static class BaseStuff {
    public DayOfWeek dayOfWeek = DayOfWeek.MONDAY;
}

public static class ClassWithStuff extends BaseStuff {
    public int inty = 1;
    public String stringy = "string";
    public Object Stuff = null;
}

例-各フィールドの名前と値の印刷:

public static void main(String[] args) throws Exception {
    ClassWithStuff cws = new ClassWithStuff();
    FieldsAndGetters.fields(cws) 
            .map(field -> field.getKey().getName() + " = " + field.getValue())
            .forEach(System.out::println);
}

出力:

inty = 1
stringy = string
Stuff = null
dayOfWeek = MONDAY

Ouptutが示すように、継承されたパブリックフィールドも考慮されます。

0
LuCio