反射
キー反射は反射リフレクションAPIは、実行時に内部情報の任意のタイプ、および内部プロパティと任意のオブジェクトを直接操作する方法によって作られたプログラムを可能にする、動的言語であると考えられます。
二、Javaリフレクションメカニズムの機能を提供
ランタイムオブジェクトで決定することは、どのクラスに属します。
任意の構成内のオブジェクトのランタイムクラスでは、
いずれかのクラスは、実行時にメンバ変数やメソッドを持って分析します。
実行時に任意のメンバ変数やオブジェクトのメソッドを呼び出します。
動的プロキシを生成します。
第三に、リフレクションAPI関連
クラスのjava.lang.Classの代わりに
クラスのメソッドjava.lang.reflect.Methodオブジェクトを表します
クラスのメンバ変数の代わりにをjava.lang.reflect.Field
代表クラスのコンストラクタjava.lang.reflect.Constructor
......
第四に、簡単な例
パブリック クラス人{ プライベート文字列名; プライベート int型の年齢; パブリック人(){ } 公共人(文字列名){ この .nameの= 名前。 } 公共人(文字列名、int型の年齢){ この .nameの= 名前。 この .age = 年齢; } パブリック文字列のgetName(){ 戻り名。 } 公共 ボイドのsetName(文字列名){ この .nameの= 名前。 } 公共 INT getAge(){ 戻り年齢; } 公共 ボイド setAge(int型の年齢){ この .age = 年齢。 } 公共 ボイドショー(){ System.out.printlnは( "我是一个人" )。 } 公共 ボイド表示(文字列国){ するSystem.out.println( "我的国籍是" + 国)。 } @Override パブリック文字列のtoString(){ 戻り "人物[NAME =" +名+ "年齢=" + 年齢。 } } インポート org.junit.jupiter.api.Test; インポートをjava.lang.reflect.Fieldとして、 パブリック クラスTestReflection { // クラスのオブジェクトの前に反射を作成し、メソッドとプロパティを呼び出す @Test 公共 ボイド(TEST1)を{ 人人 = 新しい新規人物(); person.setAge( 10 ); person.setName( "ボブ" ) のSystem.out.println(人物); person.show(); person.display( "中国" ); } // 前に反射して、オブジェクトのクラスを作成し、構造を呼び出す @Test 公共 ボイド)(TEST2スローIllegalAccessExceptionが、ないInstantiationExceptionは、持たないNoSuchFieldException {ある クラスの<person> clazz =人。クラス; // 対応するオブジェクトclazzランタイム・クラス・クラス人作成 者人物= clazz.newInstanceを(); のSystem.out.println(人物) フィールド、F1 = clazz.getField( "名前" ); f1.set(人、 "漢Meimei" ); のSystem.out.println(人物); } }
TEST2を実行することができる()するときは、次の例外を投げ返します。
いいえ、「名前」属性が存在しません。対応するフィールドが存在しないために、この例外が原因である可能性があり、またはプロパティは、プライベート、および秘密性に対応して設定されるだけでなく、反射を得ることができない、それは公的に変更することができます。
現象を修正した後です。
これは、指定したプロパティのランタイムクラスの反射を呼び出すことによって、国民は私有財産を呼び出し、指定されたメソッドも呼び出すことができます呼び出すことができますされています。
// 呼び出すパブリックプロパティ
フィールド、F1 = clazz.getField( "名前" );
f1.set(人、 "漢Meimei" ); System.out.printlnは(人); // プライベートプロパティを呼び出すには、getDeclaredField文はオフに呼び出しますプロパティ、 // setAccessibleセットアクセス権限 フィールド、F2 = clazz.getDeclaredField( "年齢" ); f2.setAccessible(真の); f2.set(人、 20 ); のSystem.out.println(人物)
// 反射によって指定されたメソッドの実行時クラス呼び出すため の方法であって、法1 = clazz.getMethod(「ショー」); method1.invoke(人物); 方法、方法2 = clazz.getMethod(「表示」、文字列。クラス); // 追加メソッドのパラメータ型 method2.invoke(人、「中国中国」);
5
1、Classクラス
まず、元の反射であるクラスのクラスを、理解して
すべてのクラスはClassクラスを返すのgetClass()メソッドは、特定のオブジェクトで実行されるクラスにObjectクラスから継承します。
オブジェクトを生成する方法は、通常は2つです:
ノーマルモード:必要な名前「バッグ」を導入 - >新しいインスタンス化することによって - >オブジェクトのインスタンスを取得します。
反射モード:インスタンスオブジェクト - >のgetClass()メソッド - >完全な「パケットタイプ」名を取得します
手短に言えば:反射、すなわち、オブジェクト・クラスの名前によって反射が袋のインスタンスから、決定された後、再びランタイムクラス構造は、内部に見下ろし、ランタイム・クラス・インスタンスから取得曲がります。オブジェクトのミラーは、独自のプロパティ、メソッド、およびコンストラクタは、などの情報をインタフェースを実装し得ることができます。
クラスは、クラス自体で、Classオブジェクトは、システムによってのみ作成することができ、JVM内のクラスは、クラスの唯一のインスタンスになり、JVMに対応するClassオブジェクトは、クラスの各インスタンスは覚えているだろう、の.classファイルにロードされていていますクラスの例により生成され、完全な構造は、クラスのクラスによって得ることができます。
@Test 公共 ボイドTest3は(){ 人人 = 新しい新規人物(); // クラスオブジェクト実行時のgetClass介して()、ランタイムクラス返す クラスclazz = person.getClassを(); のSystem.out.println(clazz) ; }
出力:
私たちは、クラスを作成し、(のjavac.exe)をコンパイルし、対応する.classファイルを生成します
ロードした後、これは.classファイル(のjava.exeを、JVMのクラスローダによって行われます)
このの.classファイルがメモリにロードされた後、キャッシュに保存されているランタイムクラス、で、その後、ランタイムクラス自体は、クラスのインスタンスです。
クラスのロードごとに一度だけ実行されます。