概要
リフレクションとは、プログラムの実行時にイントロスペクション機能とも呼ばれるクラス機能を分析できるプログラムのことで、主にアプリケーションではなくツールプログラムの構築に使用されます。
リフレクションメカニズムの役割には、次の4つのポイントが含まれます。
- ランタイム分析クラス
- 実行時にオブジェクトを表示する
- 一般的な配列操作を実装する
- 使用方法
Javaのリフレクションメカニズムは、主に次のクラスを通じて実装されます:クラス、コンストラクター
関連するクラスとメソッド
クラス
クラス(型を表すクラスは、実際にはジェネリッククラスですが、型パラメーターを無視して、元のクラスを直接使用できます):クラスオブジェクトを取得する方法は?これは、任意のJavaタイプ(またはvoid)クラスメソッド、またはオブジェクトのgetClassメソッドによって取得できます。
一般的な方法は次のとおりです。
- getName
- 指定されたクラス名に対応するClassオブジェクトを取得するためのforName-staticファクトリメソッド
- newInstance-クラス型のオブジェクトを取得する
- getFields、getMethods、getConstructor(パブリックフィールドまたはメソッド)
- getDeclaredFie1ds、getDeclareMethods、getDeclaredConstructors(すべてのフィールドまたはメソッドですが、継承されません)
フィールド、メソッド、コンストラクタ
一般的な方法
- getName
- getModifiers–Modifier.toString
- setAccessible-実行時にメンバーのアクセス制限を変更できます
フィールド
- getType
- 取得、設定
方法
- 呼び出す
「Java Core Technology-Volume One」のアプリケーションの典型的な例は、リフレクションメカニズムを使用してクラスのメンバーを解析および出力することです。コード例は次のとおりです。
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
/**
* @description: this program uses reflection to print all features of a class
* @author: lyg89
* @create: 2019-03-23 23:10
**/
public class ReflectionTest {
public static void main(String[] args) {
String name;
if (args.length > 0) {
name = args[0];
} else {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date):");
name = scanner.next();
}
try {
Class<?> aClass = Class.forName(name);
String modifiers = Modifier.toString(aClass.getModifiers());
if (modifiers.length() > 0) {
System.out.print(modifiers + " ");
}
System.out.print("class " + name);
Class<?> superclass = aClass.getSuperclass();
if (superclass != null && superclass != Object.class) {
System.out.print(" extends " + superclass.getName());
}
System.out.print("\n{\n");
printConstructors(aClass);
System.out.println();
printMethods(aClass);
System.out.println();
printFields(aClass);
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.exit(0);
}
private static void printConstructors(Class clazz) {
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.print(" ");
int modifiers = constructor.getModifiers();
String strModifier = Modifier.toString(modifiers);
if (strModifier.length() > 0) {
System.out.print(strModifier + " ");
}
System.out.print(clazz.getName() + " (");
Class[] parameterTypes = constructor.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(parameterTypes[i].getName());
}
System.out.println(");");
}
}
private static void printMethods(Class clazz) {
for (Method method : clazz.getMethods()) {
System.out.print(" ");
int modifiers = method.getModifiers();
String strModifier = Modifier.toString(modifiers);
if (strModifier.length() > 0) {
System.out.print(strModifier + " ");
}
Class<?> returnType = method.getReturnType();
System.out.print(returnType.getName() + " " + method.getName() + " (");
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(parameterTypes[i].getName());
}
System.out.println(");");
}
}
private static void printFields(Class clazz) {
for (Field field : clazz.getFields()) {
System.out.print(" ");
int modifiers = field.getModifiers();
String strModifier = Modifier.toString(modifiers);
if (strModifier.length() > 0) {
System.out.print(strModifier + " ");
}
System.out.println(field.getType().getName() + " " + field.getName() + ";");
}
}
}
まとめ
リフレクションメカニズムは、Javaタイプ、オブジェクト、メソッドなどを含む、プログラムの実行中にプログラムのメタ情報にアクセスするのに役立ち、オブジェクトを動的に作成したり、オブジェクトのアクセス制御制限を変更したりすることもできますが、Java 9のモジュールメカニズムは開始しましたsetAccessibleにはいくつかの制限があります。リフレクション機構を利用して強力なツールセットを構築できるため、多くのフレームワークで使用されており、リフレクションを理解することで、プログラムの設計に求められる柔軟性をより深く理解できると言えます。