Javaのリフレクションのサンプルです。
目次
サンプル | リフレクションとは |
クラスの情報を取得する(クラス.class) | |
クラスの情報を取得する(getClass) | |
クラスの情報を取得する(Class.forName) | |
メンバー変数を取得する(getDeclaredFields) | |
メソッドを取得する(getDeclaredMethods) | |
メソッドを実行する(invoke) | |
privateのメンバー変数を変更する |
リフレクションとは
- クラスの情報を扱う機能です。
- メンバー変数やメソッドの情報などを取得できます。
- クラス情報の取得は、複数のやり方があります。
- アノテーション作成時にも使用できます。
Java 独自のアノテーションで値を取得するサンプル
Classクラス
- プログラム実行中にメンバー変数やメソッド情報等を取得できます。
- 以下はJava8 API仕様のClassクラスのリンクです。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Class.html
Methodクラス
- Methodクラスのinvokeメソッドでメソッドを実行できます。
- 以下はJava8 API仕様のMethodクラスのリンクです。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/reflect/Method.html
クラスの情報を取得する(クラス.class)
Class<?> 変数 = クラス.class; |
クラス情報を取得したいクラス名に.classを追加して、クラス情報のインスタンス(Classクラス)を取得します。
package test1;
public class Test1 {
public static void main(String[] args) {
Class<?> c = Color.class;
System.out.println(c.getSimpleName()); //Color
System.out.println(c.getPackage()); //package test1
System.out.println(c.getName()); //test1.Color
}
}
class Color {
}
6行目のColor.classで、13行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
8行目のgetSimpleNameメソッドは、クラス名を表示します。
9行目のgetPackageメソッドは、パッケージ名を表示します。
10行目のgetNameメソッドは、パッケージ名+クラス名(FQCN)を表示します。
クラスの情報を取得する(getClass)
Class<?> 変数 = インスタンスの変数.getClass(); |
インスタンスの変数とgetClassメソッドで、クラス情報のインスタンス(Classクラス)を取得します。
package test1;
public class Test1 {
public static void main(String[] args) {
Color cl = new Color();
Class<?> c = cl.getClass();
System.out.println(c.getSimpleName()); //Color
System.out.println(c.getPackage()); //package test1
System.out.println(c.getName()); //test1.Color
}
}
class Color {
}
6行目は、14行目のクラスをインスタンス化しています。
7行目は、getClassメソッドで14行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
getClassメソッドはObjectクラスにあるメソッドです。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Object.html#getClass--
9行目のgetSimpleNameメソッドは、クラス名を表示します。
10行目のgetPackageメソッドは、パッケージ名を表示します。
11行目のgetNameメソッドは、パッケージ名+クラス名(FQCN)を表示します。
クラスの情報を取得する(Class.forName)
Class<?> 変数 = Class.forName(クラス); |
Class.forNameと引数にクラスを指定して、クラス情報のインスタンス(Classクラス)を取得します。
package test1;
public class Test1 {
public static void main(String[] args) {
try {
Class<?> c = Class.forName("test1.Color");
System.out.println(c.getSimpleName()); //Color
System.out.println(c.getPackage()); //package test1
System.out.println(c.getName()); //test1.Color
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Color {
}
7行目のClass.forNameで、17行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
Class.forNameを使用する場合、try-catchでの例外処理が必要です。
9行目のgetSimpleNameメソッドは、クラス名を表示します。
10行目のgetPackageメソッドは、パッケージ名を表示します。
11行目のgetNameメソッドは、パッケージ名+クラス名(FQCN)を表示します。
メンバー変数を取得する(getDeclaredFields)
public Field[] getDeclaredFields() throws SecurityException |
public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException |
- ClassクラスのgetDeclaredFieldsメソッドでメンバー変数を取得します。
- 以下は、OracleのJavaのClassクラスのgetDeclaredFieldsメソッドのリンクです。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Class.html#getDeclaredFields--
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Class.html#getDeclaredField-java.lang.String-
メンバー変数を取得するサンプルです。
package test1;
import java.lang.reflect.Field;
public class Test1 {
public static void main(String[] args) {
Class<Color> c = Color.class;
Field[] aaa = c.getDeclaredFields();
for (Field a : aaa) {
System.out.println(a);
//private java.lang.String test1.Color.moji
//private java.lang.String test1.Color.name
}
}
}
class Color {
private String moji = "色は";
private String name;
}
10行目は、getDeclaredFieldsメソッドで19行目のクラスのメンバー変数を取得しています。
戻り値は、配列です。
12-16行目は、拡張for文で取得した値を表示しています。
メソッドを取得する(getDeclaredMethods)
public Method[] getDeclaredMethods() throws SecurityException |
- ClassクラスのgetDeclaredMethodsメソッドでメソッドを取得します。
- 以下は、OracleのJavaのClassクラスのgetDeclaredMethodsメソッドのリンクです。
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Class.html#getDeclaredMethods--
メソッドを取得するサンプルです。
package test1;
import java.lang.reflect.Method;
public class Test1 {
public static void main(String[] args) {
Class<Color> c = Color.class;
Method[] bbb = c.getDeclaredMethods();
for (Method a : bbb) {
System.out.println(a);
//public java.lang.String test1.Color.getName()
//public void test1.Color.setName(java.lang.String)
}
}
}
class Color {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
10行目は、getDeclaredMethodsメソッドで19行目のクラスのメソッドを取得しています。
戻り値は、配列です。
12-16行目は、拡張for文で取得した値を表示しています。
メソッドを実行する(invoke)
メソッドを実行するサンプルです。
package test1;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test1 {
public static void main(String[] args) {
Color color = new Color();
Class<?> c1 = color.getClass();
Method method1;
Method method2;
try {
method1 = c1.getMethod("setName", String.class);
method1.invoke(color, "オレンジ");
method2 = c1.getMethod("getName");
String result = (String) method2.invoke(color);
System.out.println(result); //色はオレンジ
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
class Color {
private String moji = "色は";
private String name;
public String getName() {
return moji + name;
}
public void setName(String name) {
this.name = name;
}
}
10行目は、getClassメソッドで38行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
15-21行目は、ClassクラスのgetMethodとMethodクラスのinvokeメソッドで42,45行目のメソッドを実行しています。
privateのメンバー変数を変更する
privateのメンバー変数を変更するサンプルです。
本来、privateのメンバー変数はクラスの外部から変更できませんが、リフレクションを使用すると可能になります。
package test1;
import java.lang.reflect.Field;
public class Test1 {
public static void main(String[] args) {
Color color = new Color();
Class<?> c1 = color.getClass();
Field a1;
try {
a1 = c1.getDeclaredField("moji");
a1.setAccessible(true);
try {
a1.set(color, "カラー");
System.out.println(color.getName()); //カラー
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
}
}
}
class Color {
private String moji;
public String getName() {
return moji;
}
}
9行目は、getClassメソッドで29行目のクラスの情報を持つClassクラスのインスタンスを取得しています。
14行目は、getDeclaredFieldメソッドで引数に30行目のメンバ変数を指定しています。
15行目は、setAccessibleメソッドでアクセスできるようにしています。
17行目は、setメソッドでprivateの変数に値をセットしています。
関連の記事