VI反射:ランタイムクラス情報
我々はすでに知っている、コンパイル時に、コンパイラは、すべてのクラスがRTTIによって処理されるように知っている必要があります。利用可能な方法を確認するため、およびメソッドの名前を返す - それはメカニズムを提供反映しました。違いは、プロセス既知のRTTIクラスと反射治療のための未知のクラス。一緒java.lang.reflectのクラスとクラスライブラリは、反射の概念をサポートし、ライブラリーは、フィールド、メソッド、およびコンストラクター(メンバー、各クラスが実装インタフェース)を備えます。これらのタイプは、JVMの実行、不明に対応するクラスのメンバーを表すために使用される種類によって作成されます。コンストラクタ(コンストラクタ)は、新しいオブジェクトを作成し、フィールドは、get()、セット()メソッドに関連付けられ(フィールド)オブジェクトのフィールドを読み取って修正するために使用するオブジェクトメソッド(メソッド)を呼び出す()メソッドに関連付けられているメソッドを呼び出します。このように、クラス情報の匿名オブジェクトが完全に実行時に決済することができますが、コンパイル時に何を知っている必要はありません。
実際には、とき未知のタイプの契約の反射物、JVMは、単に何かを行う前に、オブジェクトをチェックし、あなたが最初にこのクラスのClassオブジェクトをロードする必要があります。したがって、の.classファイルのクラスは、(ローカルまたはネットワーク上で)利用可能であるので、反射とRTTI差が必要なときだけJVMのそれのための:RTTI、コンパイル時にコンパイラチェックの.classファイルとオープンは、反射があるため、の.classファイルは、コンパイル時に利用できないので、これの.classファイルが開いて実行されている確認してください。よりダイナミックなコードを作成する必要性に反映すると便利です。
七、動的プロキシ
基本的なデザインパターンをされて演技前、または、彼らは追加したいものを追加した後のオブジェクト、およびオブジェクトを制御するために、他の対象のためのエージェントを提供しています。
インターフェイスインターフェイス{ ボイドのdoSomething(); 無効doSomeOtherThing(String型の引数); } クラスRealObject実装インタフェース{ @Override 公共ボイドのdoSomething(){ System.out.printlnは( "doSomethingの")。 } @Override 公共ボイドdoSomeOtherThing(文字列引数){ するSystem.out.println( "doSomeOtherThing" +引数)。 } } クラスSimpleProxy実装インタフェース{ プライベートインターフェイスれるProxyID。 公共SimpleProxy(インタフェースれるProxyID){ this.proxyId =れるProxyID。 } @Override 公共ボイドのdoSomething(){ //元のメソッドのdoSomethingを追加これは、物事の後に、新たな機関に出力されます //購入、追加の試合後の会社のようなエージェント のSystem.out.println( "SimpleProxy doSomethingの"); proxyId.doSomething(); } @Override ます。public void doSomeOtherThing(String型の引数){ proxyId.doSomeOtherThing(引数); / /スタッフは、元のすべての行の前または後に添加することができる のSystem.out.println( "SimpleProxy doSomeOtherThing" +引数); } } publicクラスSimpleProxyDemo { 静的ボイドコンシューマ(インターフェースI){ )(i.doSomething; i.doSomeOtherThing ( "GI woli GIAO李"); } 公共の静的な無効メイン(文字列[] args){ 消費者(新しい新しいRealObject())。 System.out.printlnは( "----- ----- -----")。 消費者(新SimpleProxy(新RealObject())); } }
結果:
doSomethingの doSomeOtherThingイ・ギwoli GIAO ----- ----- ----- SimpleProxy doSomethingの doSomethingの doSomeOtherThingイ・ギwoli GIAO SimpleProxy doSomeOtherThingのイ・ギwoli GIAO
消費者は()インタフェースを受け入れたので、それはRealObjectまたはSimpleProxyあるので、パラメータとして使用され、SimpleProxyは演技RealObjectは、私たち自身のことをたくさん追加足を置くことができます。
さらにJavaのダイナミックプロキシ、それは動的プロキシを作成し、動的プロキシメソッドの呼び出しを扱うことができるため、より前です。動的プロキシで行われたすべての呼び出しは、そのジョブはコールのタイプを明らかにし、適切な対策を決定することで、単一のコールプロセッサにリダイレクトされます。
輸入java.lang.reflect.InvocationHandler; 輸入java.lang.reflect.Methodオブジェクト; 輸入java.lang.reflect.Proxyの; インターフェイスインターフェイス{ ボイドのdoSomething(); 無効doSomeOtherThing(String型の引数); } クラスRealObject実装インタフェース{ @Override 公共ボイドのdoSomething(){ System.out.printlnは( "doSomethingの")。 } @Override 公共ボイドdoSomeOtherThing(文字列引数){ するSystem.out.println( "doSomeOtherThing" +引数)。 } } クラスDynamicProxyHandler実装のInvocationHandler { プライベートオブジェクトれるProxyID。 公共DynamicProxyHandler(オブジェクトれるProxyID){ this.proxyId =れるProxyID。 } @Override (オブジェクトプロキシ、メソッドのメソッド、オブジェクト[]引数)を呼び出すパブリックオブジェクトのThrowable {スロー するSystem.out.println( "****プロキシ:" + proxy.getClass()+ "方法" +方法+」を、引数:」+引数); (もし!引数= NULL){ のために(オブジェクト引数:引数){ System.out.printlnは(」 "+引数); } } 戻りmethod.invoke(れるProxyID、引数)。 } } publicクラスSimpleProxyDemo { 静的ボイドコンシューマ(インターフェースI){ i.doSomething()。 ( "イ・ギwoli GIAO")i.doSomeOtherThing。 } RealObject realObject =新しいRealObject()。 System.out.printlnは( "----- ----- -----");
//動的プロキシは何でも表現できる インタフェースのプロキシ=(インタフェース)たとえば、Proxy.newProxyInstanceを(Interface.class.getClassLoader()、新しい新しいクラス[] {} Interface.class、新しい新しいDynamicProxyHandler(realObject)); 消費者(プロキシ); } }
結果:
doSomethingの doSomeOtherThingイ・ギwoli GIAO ----- ----- ----- ****プロキシ:クラス$ Proxy0、methodpublic抽象無効Interface.doSomething()、引数:ヌル doSomethingの ****プロキシ:クラス$ Proxy0、methodpublic抽象無効Interface.doSomeOtherThing(java.lang.Stringで)、 引数:[Ljava.lang.Object; 7ea987acのYI @ GI woli GIAO doSomeOtherThingのイ・ギwoli GIAO
たとえば、Proxy.newProxyInstance()は動的プロキシを作成することによって、この方法は、3つのパラメータが必要です。
1.クラスローダ:クラスローダオブジェクトから得ることができるにロードされています。
2.プロキシを実装します(クラスや抽象クラス、唯一のインターフェイスにすることはできません)したいインタフェースのリスト。
3のInvocationHandlerインタフェースの実装。
呼び出しはまたような異なるアプローチに従う方法の名称で実施することができます。
@Override (オブジェクトプロキシ、メソッドのメソッド、オブジェクト[]引数)を呼び出すパブリックオブジェクトのThrowable {スロー するSystem.out.println( "****プロキシ:" + proxy.getClass()+ "方法" +方法+」を、引数:」+引数); (もし!引数= NULL){ のために(オブジェクト引数:引数){ System.out.printlnは(」 "+引数); } } (method.getName()に等しい( "doSomethingの")。){場合 のSystem.out.println( "これはdoSomethingのためのプロキシです")。 } method.invoke(れるProxyID、引数)を返します。 }
また、メソッドのパラメータのより多くの操作を実行できるか、あなたが持っているので、彼らはそれが~~ 10以内にそれを買う追加する前に、弁護士のあなたの力を使用することを楽しみます。
九、インターフェイスの型情報
重要な目標は、それによって結合を低減、プログラマインタフェースキーワードスペーサ部材をできるようにすることです。リフレクション、あなたもプライベート、すべてのメソッドを呼び出すことができます。アローンシステムは、任意の変更の試みを受け入れていますが、変更内容は、実際に実行時に発生しません任意の異常な状況を投げないであろう、最終的なもので、変更することはできません。
ボイドcallMethod(オブジェクトA、文字列methodNameに)例外{スロー メソッドメソッド= a.getClassを()getDeclaredMethod(methodNameの)。 method.setAccessible(真の); method.invoke()。 }
http://www.72177.com/htm/201911/25/4507597.htm
http://www.72177.com/htm/201911/25/4507596.htm
http://www.72177.com/htm/ 25分の201911 / 4507564.htm
http://www.72177.com/htm/201911/25/4507562.htm
http://www.72177.com/htm/201911/25/4507560.htm
のhttp:// WWW .72177.com / HTM / 25分の201911 / 4507558.htm
http://www.72177.com/htm/201911/25/4507555.htm
http://www.72177.com/htm/201911/25/4507553 .htmの
http://www.72177.com/htm/201911/25/4507551.htm
http://www.72177.com/htm/201911/25/4507549.htm
http://www.72177.com/ HTM / 25分の201911 / 4507546.htm
http://www.72177.com/htm/201911/25/4507544.htm
http://www.72177.com/htm/201911/25/4507542.htm
のhttp:/ /www.72177.com/htm/201911/25/4507540.htm
http://www.72177.com/htm/201911/25/4507538.htm
http://www.72177.com/htm/201911/25/4507535.htm
http://www.72177.com/htm/ 25分の201911 / 4507533.htm
http://www.72177.com/htm/201911/25/4507531.htm
http://www.72177.com/htm/201911/25/4507529.htm
のhttp:// WWW .72177.com / HTM / 25分の201911 / 4507526.htm
http://www.72177.com/htm/201911/25/4507524.htm
http://www.72177.com/htm/201911/25/4507522 .htmの
http://www.72177.com/htm/201911/25/4507520.htm
http://www.72177.com/htm/201911/25/4507517.htm
http://www.72177.com/ HTM / 25分の201911 / 4507515.htm