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
}
これを達成する方法はありますか?
[クラス]で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 )
はい、反射で。
Class
オブジェクトを使用して、 getFields()
メソッドでField
オブジェクトにアクセスします。
_Field[] fields = ClassWithStuff.class.getFields();
_
次に、フィールドをループします。これは、宣言したすべてのフィールドがpublic
であるため機能します。そうでない場合は、 getDeclaredFields()
を使用します。これは、クラスで直接宣言されているすべてのFields
、public
にアクセスします。
探しているのは reflection です。 Reflectionを使用すると、独自のクラスまたは別のクラスを調べて、それが何で構成されているかを確認できます。 Javaにはリフレクションが組み込まれているため、すぐに使用できます。その後、次のようなことができます-
for(Field f : ClasWithStuff.getFields()){
System.out.println(f.getName());//or do other stuff with it
}
これを使用して、メソッドやコンストラクターなどを取得し、同様の優れた機能を実行することもできます。
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が示すように、継承されたパブリックフィールドも考慮されます。