反射
Javaリフレクションメカニズムを介して、JVMにロードされたJavaオブジェクトの記述にプログラムでアクセスでき、Javaオブジェクト自体を記述する情報にアクセス、検出、および変更する機能を実現できます。リフレクションを通じて、コンストラクター、メンバー変数、およびメンバーメソッドにアクセスできます。
メンバ変数へのアクセス:メンバ変数にJavaリフレクション・アクセス
メンバメソッドへのアクセス:メンバー・メソッドにJavaリフレクション・アクセス
アクセスコンストラクタ
Constructorオブジェクトを使用して、対応する構築メソッドを操作します。
Constructorクラスで提供される一般的なメソッド:
方法 | 説明 |
---|---|
isVarArgs() | 構築メソッドが可変数のパラメーターを許可するかどうかを確認し、許可されている場合はtrueを返し、そうでない場合はfalseを返します。 |
getParameterTypes() | コンストラクターのパラメーター型を宣言順にClass配列の形式で取得する |
gerExceptionTypes() | コンストラクタがクラス配列の形式でスローする可能性のある例外を取得します |
newInstance(Object…initargs) | この構築メソッドを使用して、指定したパラメーターでこのクラスのオブジェクトを作成します。パラメーターが設定されていない場合は、パラメーターなしのデフォルトの構築メソッドを採用することを意味します |
setAccessible(ブールfasg) | 構築メソッドの修飾子がプライベートの場合、デフォルトでは、リフレクションを介してオブジェクトを作成することはできません。メソッドを実行し、entryパラメーターをtrueに設定して、 |
getModifiers() | 構築メソッドで使用される修飾子を解析できる整数を取得します |
getModifiers()メソッドの戻り値は、表現された修飾子情報です。このクラスでは、解析のための一連の静的メソッドが提供されています。指定された修飾子によって変更されているかどうかを確認できるだけでなく、それらすべてを文字列の形式で取得することもできます修飾子。
Modifierクラスの一般的な分析メソッド:
静的メソッド | 説明 |
---|---|
isPublic(int mod) | それがtrueの場合はpublic修飾子によって変更されているかどうかを確認し、そうでない場合はfalseを返します。 |
isProtected(int mod) | プロテクトモディファイヤによって変更されているかどうかをチェックします。trueの場合はfalseを返します。 |
isPrivate(int mod) | trueの場合、private修飾子によって変更されているかどうかを確認し、そうでない場合はfalseを返します。 |
isStatic(int mod) | static修飾子によって変更されているかどうかを確認します。trueの場合はfalseを返します。 |
isFinal(int mod) | 最終モディファイアによって変更されているかどうかを確認します。trueの場合はfalseを返します。 |
toString(int mod) | すべての修飾子を文字列として返します |
最初に変数を作成し、いくつかのコンストラクターとtoStringメソッドを作成します。
public class Study {
int id;
String name;
double price;
// 创建无参构造方法
public Study() {
super();
}
// 创建有一个参数的构造方法
public Study(int id) {
super();
this.id = id;
}
// 创建私有的并且有三个参数的构造方法
private Study(int id, String name, double price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
public String toString() {
return "Study [id=" + id + ", name=" + name + ", price=" + price + "]";
}
}
上記で作成したStudyクラスを反映する別のStudy2クラスを作成します。
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("study.czm.Study");//创建class对象
//获取构造方法
Constructor cos[] = c.getConstructors();
for(Constructor cs:cos) {
System.out.println(Modifier.toString(cs.getModifiers()));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
操作結果:
Studyクラス構築メソッドの修飾子を正常に取得しました。getConstructors()メソッドが呼び出されるため、パブリック変更のみを取得できるすべてのメソッドが、getDeclaredConstructors()メソッドに変更され、すべてのメソッドの修飾子を取得します
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("study.czm.Study");//创建class对象
//获取构造方法
Constructor cos[] = c.getDeclaredConstructors();
for(Constructor cs:cos) {
System.out.print(Modifier.toString(cs.getModifiers()) + " ");//获取修饰符
System.out.print(cs.getName() + "(");//获取方法名
Class p[] = cs.getParameterTypes();//获取参数
for(int i=0; i<p.length; i++) {
System.out.print(p[i].getSimpleName()+" arge ");
}
System.out.println(") { }");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
これで、メソッド名、パラメーターを含むすべての構築メソッドが取得されました。
ループの外側に引数のないコンストラクターオブジェクトを作成する
//创建对象
Constructor cst1 = c.getDeclaredConstructor();//无参构造方法
Object obj = cst1.newInstance();//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
これは基本的に、反映されたStudyクラスのパラメーターなしのコンストラクターであり、
その中の変数はすべてデフォルト値です。
パラメータ化されたコンストラクタを作成し、IDに値を割り当てます
Constructor cst2 = c.getDeclaredConstructor(int.class);//有参构造方法
obj = cst2.newInstance(123);//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
idの値は123になり
、最後の構築メソッドを作成します。これには3つのパラメーターがあり、修飾子はプライベートです。さらに3つのパラメーターを割り当てる
Constructor cst3 = c.getDeclaredConstructor(int.class,String.class,double.class);//有参构造方法
obj = cst2.newInstance(-1,"反射",3.14);//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
このように直接実行すると、エラーが発生します。その修飾子はプライベートなので、操作するための権限を取得し、コード行setAccessible(true)を追加して、パラメーターをtrueに設定する必要があります。
Constructor cst3 = c.getDeclaredConstructor(int.class,String.class,double.class);//有参构造方法
cst3.setAccessible(true);//获取操作权限
obj = cst3.newInstance(-1,"反射",3.14);//创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
だから問題はありません
完全なコード:
public class Study2 {
public static void main(String[] args) {
try {
Class c = Class.forName("study.czm.Study");// 创建class对象
// 获取构造方法
Constructor cos[] = c.getDeclaredConstructors();
for (Constructor cs : cos) {
System.out.print(Modifier.toString(cs.getModifiers()) + " ");// 获取修饰符
System.out.print(cs.getName() + "(");// 获取方法名
Class p[] = cs.getParameterTypes();// 获取参数
for (int i = 0; i < p.length; i++) {
System.out.print(p[i].getSimpleName() + " arge ");
}
System.out.println(") { }");
}
// 创建对象
Constructor cst1 = c.getDeclaredConstructor();// 无参构造方法
Object obj = cst1.newInstance();// 创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
Constructor cst2 = c.getDeclaredConstructor(int.class);// 有参构造方法
obj = cst2.newInstance(123);// 创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
Constructor cst3 = c.getDeclaredConstructor(int.class, String.class, double.class);// 有参构造方法
cst3.setAccessible(true);// 获取操作权限
obj = cst3.newInstance(-1, "反射", 3.14);// 创建Object对象,这个Object对象实质上就是Study类反射出来的对象
System.out.println(obj.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
実行結果: