JavaのリフレクションAPIでフィールド取得
JavaのリフレクションAPIでフィールドの取得を試してみたメモです。
前回の続きで、JavaのリフレクションAPIを利用して、フィールドの取得を試してみました。
java.lang.reflect.Field
JavaのリフレクションAPIを利用することで、メタデータにアクセスできます。
java.lang.reflect.Fieldクラスを利用してフィールドの取得を試したいと思います。
テスト用クラス
Mavenプロジェクトを作成し、pom.xmlはjunitとhamcrestだけdependencyに追加しました。
pom.xml
<dependencies> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-all</artifactId> <version>1.3</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit-dep</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies>
テスト対象のクラスは下記のようなクラスを作りました。
ReflectFieldExample.java
package reflect; public class ReflectFieldExample { public String pub = "public"; protected String pro = "protected"; String def = "default"; private String pri = "private"; String name; public ReflectFieldExample() { this("no args"); } public ReflectFieldExample(String name) { this.name = name; } }
public、protected、修飾子なし、private
のアクセス修飾子でそれぞれフィールドを定義しました。
Fieldオブジェクト
Fieldオブジェクトを取得するためのメソッドは下記です。
すべてClassクラスのメソッドです。
メソッド | 戻り値 | 取得可能なアクセス修飾子 |
---|---|---|
getField | Field | public |
getFields | Field[] | public |
getDeclaredField | Field | すべて |
getDeclaredFields | Field[] | すべて |
getField()
getField()では、自クラスまたはインターフェースのフィールドが取得できます。
取得できるのはpublicフィールドのみです。
引数にはフィールド名の文字列を指定します。
Field field = ReflectFieldExample.class.getField("pub");
privateフィールドは取得できません。
// エラー Field field = ReflectFieldExample.class.getField("pri");
テストコード。
public static class getFieldの確認 { @Test public void getTypeでpublicフィールドの型が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); Class type = field.getType(); assertThat(type, is(equalTo(String.class))); } @Test(expected = java.lang.NoSuchFieldException.class) public void getTypeでprotectedフィールドの型が取得できないこと() throws Exception { Field field = ReflectFieldExample.class.getField("pro"); } @Test(expected = java.lang.NoSuchFieldException.class) public void getTypeでdefaultフィールドの型が取得できないこと() throws Exception { Field field = ReflectFieldExample.class.getField("def"); } @Test(expected = java.lang.NoSuchFieldException.class) public void getTypeでprivateフィールドの型が取得できないこと() throws Exception { Field field = ReflectFieldExample.class.getField("pri"); } }
getFields()
getFields()では、自クラスまたはインターフェースのフィールドがFieldクラスの配列で取得できます。
取得できるのはpublicフィールドのみです。
テストコード。
public static class getFieldsの確認 { @Test public void getFieldsでフィールドオブジェクトが取得できること() throws Exception { Class clazz = ReflectFieldExample.class; Field[] fields = clazz.getFields(); Field[] expected = { clazz.getField("pub") }; assertThat(fields, is(arrayContainingInAnyOrder(expected))); } }
getDeclaredField()
getDeclaredField()では、getFieldと同様にフィールドが取得できますが、
すべてのアクセス修飾子(public、protected、デフォルト、private)のフィールドが取得できます。
// publicフィールド Field field = ReflectFieldExample.class.getDeclaredField("pub"); // protectedフィールド Field field = ReflectFieldExample.class.getDeclaredField("pro"); // defaultフィールド Field field = ReflectFieldExample.class.getDeclaredField("def"); // privateフィールド Field field = ReflectFieldExample.class.getDeclaredField("pri");
テストコード。
public static class getDeclaredFieldの確認 { @Test public void getModifiersでpublicフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("pub"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PUBLIC)); } @Test public void getModifiersでprotectedフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("pro"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PROTECTED)); } @Test public void getModifiersでdefaultフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("def"); int mod = field.getModifiers(); assertThat(mod, is(0)); } @Test public void getModifiersでprivateフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("pri"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PRIVATE)); } }
getDeclaredFields()
getDeclaredFields()では、getFields同様にFieldクラスの配列で取得できますが、
getFields()と異なり、すべてのアクセス修飾子(public、protected、デフォルト、private)のフィールドが取得できます。
テストコード。
public static class getDeclaredFieldsの確認 { @Test public void getDeclaredFieldsでフィールドオブジェクトが取得できること() throws Exception { Class clazz = ReflectFieldExample.class; Field[] fields = clazz.getDeclaredFields(); Field[] expected = { clazz.getDeclaredField("pub"), clazz.getDeclaredField("pro"), clazz.getDeclaredField("def"), clazz.getDeclaredField("pri"), clazz.getDeclaredField("name") }; assertThat(fields, is(arrayContainingInAnyOrder(expected))); } }
Fieldクラス
フィールド情報取得
Fieldクラスのメソッドを利用してフィールドの情報が取得できます。
Field field = ReflectFieldExample.class.getField("pub"); // フィールド名取得 String name = field.getName(); // フィールドのアクセス修飾子取得 int mod = field.getModifiers(); // フィールドを表す文字列を取得 String generic = field.toGenericString();
テストコード。
public static class Fieldクラスでフィールド情報取得 { @Test public void getNameでフィールドの名前が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); String name = field.getName(); assertThat(name, is("pub")); } @Test public void getModifiersでフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PUBLIC)); } @Test public void toGenericStringでフィールドを表す文字列が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); String generic = field.toGenericString(); assertThat(generic, is("public java.lang.String reflect.ReflectFieldExample.pub")); } }
テストコード
今回のテストコードの全体です。
ReflectFieldExampleTest.java
package reflect; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.junit.Assert.*; /** * Created by pppurple on 2016/07/23. */ @RunWith(Enclosed.class) public class ReflectFieldExampleTest { public static class getFieldの確認 { @Test public void getTypeでpublicフィールドの型が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); Class type = field.getType(); assertThat(type, is(equalTo(String.class))); } @Test(expected = java.lang.NoSuchFieldException.class) public void getTypeでprotectedフィールドの型が取得できないこと() throws Exception { Field field = ReflectFieldExample.class.getField("pro"); } @Test(expected = java.lang.NoSuchFieldException.class) public void getTypeでdefaultフィールドの型が取得できないこと() throws Exception { Field field = ReflectFieldExample.class.getField("def"); } @Test(expected = java.lang.NoSuchFieldException.class) public void getTypeでprivateフィールドの型が取得できないこと() throws Exception { Field field = ReflectFieldExample.class.getField("pri"); } } public static class getFieldsの確認 { @Test public void getFieldsでフィールドオブジェクトが取得できること() throws Exception { Class clazz = ReflectFieldExample.class; Field[] fields = clazz.getFields(); Field[] expected = { clazz.getField("pub") }; assertThat(fields, is(arrayContainingInAnyOrder(expected))); } } public static class getDeclaredFieldの確認 { @Test public void getModifiersでpublicフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("pub"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PUBLIC)); } @Test public void getModifiersでprotectedフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("pro"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PROTECTED)); } @Test public void getModifiersでdefaultフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("def"); int mod = field.getModifiers(); assertThat(mod, is(0)); } @Test public void getModifiersでprivateフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getDeclaredField("pri"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PRIVATE)); } } public static class getDeclaredFieldsの確認 { @Test public void getDeclaredFieldsでフィールドオブジェクトが取得できること() throws Exception { Class clazz = ReflectFieldExample.class; Field[] fields = clazz.getDeclaredFields(); Field[] expected = { clazz.getDeclaredField("pub"), clazz.getDeclaredField("pro"), clazz.getDeclaredField("def"), clazz.getDeclaredField("pri"), clazz.getDeclaredField("name") }; assertThat(fields, is(arrayContainingInAnyOrder(expected))); } } public static class Fieldクラスでフィールド情報取得 { @Test public void getNameでフィールドの名前が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); String name = field.getName(); assertThat(name, is("pub")); } @Test public void getModifiersでフィールドのアクセス修飾子が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); int mod = field.getModifiers(); assertThat(mod, is(Modifier.PUBLIC)); } @Test public void toGenericStringでフィールドを表す文字列が取得できること() throws Exception { Field field = ReflectFieldExample.class.getField("pub"); String generic = field.toGenericString(); assertThat(generic, is("public java.lang.String reflect.ReflectFieldExample.pub")); } } }
ソースはあげておきました。
github.com
終わり。