java.lang.reflectパッケージの浅い分析
4916 ワード
Object(ソース)
Javaはすべて対象です
Objectは反射の元
Classは反射の監督です
Class(監督)
Javaプログラムが実行されると、JVMはすべてのオブジェクトに対してユニークなタイプIDを維持します.これがClassオブジェクトです.
Javaの基本タイプとキーワードvoidもクラスオブジェクトに対応しています.同じ要素タイプと次元の配列もClassオブジェクトに対応します.
Classオブジェクトを取得する方法:のオブジェクトが通過する.class オブジェクトはgetClassメソッド を介して Class.forName(String)
Classオブジェクトにはいくつかの重要な方法があります. getConstructorシリーズ、構築方法 を取得するために使用される getFieldシリーズ、属性 を取得するために使用される getMethodシリーズ、取得方法 上記のシリーズにはDeclaredシリーズが含まれており、現在のオブジェクトのすべてのタイプの反射(privateを含む)を取得できますが、親の反射は取得できません.
Constructor、Field、MethodはClass監督の3つの利器で、いずれも
Constructor
Classオブジェクトで取得したConstructorオブジェクトの後、最も一般的な操作はオブジェクトをインスタンス化し、newInstanceメソッドを呼び出すことです.
実はClassオブジェクトにもnewInstanceメソッドがあり、オブジェクトをインスタンス化するのにも使えますが、その違いは何ですか? Class.NewInstance()は、非パラメトリック構造関数、すなわちデフォルトの構造関数のみを呼び出すことができ、呼び出された構造関数が可視であること、すなわちpublicタイプであることが要求される. Constructor.NewInstance()は、入力されたパラメータに基づいて任意の構造構造関数を呼び出すことができ、特定の場合、プライベートな構造関数を呼び出すことができる.
Demo
シーンを使用:
インタフェースモードを使用する場合、newを使用してドアのオブジェクトを作成します.Door door=new WoodenDoor()です.他のドアに変更する場合は、コードを変更する必要があります.Door door=new OtherDoor()です.したがって、ファクトリモデルを使用し、必要なドアを使用してドアを生産する必要があります.newInstance()メソッドを使用して生産する場合は、プロファイルを変更するだけです.
Field
Classオブジェクトで取得したFieldオブジェクトを使用すると、オブジェクトのプロパティ値を自由に表示および設定できます.
主な方法: get(Object object)特定オブジェクトの属性値を表示する set(Object object,Object value)特定オブジェクトに属性 を設定する. setAccessible(boolean flag)privateメンバーにpublic権限を持たせる Demo
Constructor、Field、MethodはすべてAccessibleObject類から受け継がれているため、すべてsetAccessibleの方法を持っていて、個人的にsetAccessibleは少しプライバシーを覗いている感じがして、ハハハ、Class監督がどう見ているか分かりません.
Method
Classオブジェクトで取得したMethodオブジェクトの後、考えなくてもいいですよ.メソッドを取得して何を呼び出さないのか、私たちが最もよく使う操作はinvokeメソッドです.
皆さんはinvokeに慣れていないと思います.多くの異常のため、最後にinvoke方法に位置づけられます.
invoke(Object receiver,Object...args)は、receiverパラメータを渡す方法と、nullを渡す方法の2つに分けられます.
最後に一言
本稿では,Clssオブジェクトおよびreflectパケット下のオブジェクトの簡単な使用説明にすぎず,反射の実現と原理については,さらに深く検討する必要がある.例えば、AccessibleObjectオブジェクトおよび対応するxxxAccessorの実装.
Javaはすべて対象です
Objectは反射の元
Classは反射の監督です
Class(監督)
Javaプログラムが実行されると、JVMはすべてのオブジェクトに対してユニークなタイプIDを維持します.これがClassオブジェクトです.
Javaの基本タイプとキーワードvoidもクラスオブジェクトに対応しています.同じ要素タイプと次元の配列もClassオブジェクトに対応します.
Classオブジェクトを取得する方法:
Classオブジェクトにはいくつかの重要な方法があります.
Constructor、Field、MethodはClass監督の3つの利器で、いずれも
java.lang.reflect
パックの下にあり、次はそれぞれこの3つの利器を展示します.Constructor
Classオブジェクトで取得したConstructorオブジェクトの後、最も一般的な操作はオブジェクトをインスタンス化し、newInstanceメソッドを呼び出すことです.
実はClassオブジェクトにもnewInstanceメソッドがあり、オブジェクトをインスタンス化するのにも使えますが、その違いは何ですか?
Demo
//Class.newInstance()
// public
A a = (A)Class.forName(A.class.getName()).newInstance();
//Constructor.newInstance()
Class c= Class.forName(A.class.getName());
/* 、 */
//
Constructor c0=c.getDeclaredConstructor();
//
c0.setAccessible(true);
A a0=(A)c0.newInstance();
// ,
/* 、 */
Constructor c1=c.getDeclaredConstructor(new Class[]{int.class,int.class});
c1.setAccessible(true);
// ,
A a1=(A)c1.newInstance(new Object[]{5,6});
シーンを使用:
インタフェースモードを使用する場合、newを使用してドアのオブジェクトを作成します.Door door=new WoodenDoor()です.他のドアに変更する場合は、コードを変更する必要があります.Door door=new OtherDoor()です.したがって、ファクトリモデルを使用し、必要なドアを使用してドアを生産する必要があります.newInstance()メソッドを使用して生産する場合は、プロファイルを変更するだけです.
Field
Classオブジェクトで取得したFieldオブジェクトを使用すると、オブジェクトのプロパティ値を自由に表示および設定できます.
主な方法:
// Class
Class aClass = MyObject.class
// Class Field
Field field = aClass.getDeclaredField("someField");
//
field.setAccessible(true);
MyObject objectInstance = new MyObject();
//
Object value = field.get(objectInstance);
//
field.set(objetInstance, value);
Constructor、Field、MethodはすべてAccessibleObject類から受け継がれているため、すべてsetAccessibleの方法を持っていて、個人的にsetAccessibleは少しプライバシーを覗いている感じがして、ハハハ、Class監督がどう見ているか分かりません.
Method
Classオブジェクトで取得したMethodオブジェクトの後、考えなくてもいいですよ.メソッドを取得して何を呼び出さないのか、私たちが最もよく使う操作はinvokeメソッドです.
皆さんはinvokeに慣れていないと思います.多くの異常のため、最後にinvoke方法に位置づけられます.
java.lang.NullPointerException
at ......
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
invoke(Object receiver,Object...args)は、receiverパラメータを渡す方法と、nullを渡す方法の2つに分けられます.
// doSomesthing, String
Method method = MyObject.class.getMethod("doSomething", String.class);
// doSomesthing , "parameter-value1"
Object returnValue = method.invoke(null, "parameter-value1");
最後に一言
本稿では,Clssオブジェクトおよびreflectパケット下のオブジェクトの簡単な使用説明にすぎず,反射の実現と原理については,さらに深く検討する必要がある.例えば、AccessibleObjectオブジェクトおよび対応するxxxAccessorの実装.