JAVA反射機制
JAVA反射機制是在運行狀態(tài)中,對于任意一個類痴腌,都能夠知道這個類的所有屬性和方法雌团;對于任意一個對象,都能夠調用它的任意一個方法士聪;這種動態(tài)獲取的信息以及動態(tài)調用對象的方法的功能稱為java語言的反射機制锦援。
Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象剥悟;在運行時判斷任意一個類所具有的成員變量和方法灵寺;在運行時調用任意一個對象的方法曼库;生成動態(tài)代理。
1. 得到某個對象的屬性
Java代碼
? ? public Object getProperty(Object owner, String fieldName) throws Exception {?
? ? ? ? Class ownerClass = owner.getClass();?
? ? ? ? Field field = ownerClass.getField(fieldName);?
? ? ? ? Object property = field.get(owner);?
? ? ? ? return property;?
? ? }?
Class ownerClass = owner.getClass():得到該對象的Class略板。
Field field = ownerClass.getField(fieldName):通過Class得到類聲明的屬性毁枯。
Object property = field.get(owner):通過對象得到該屬性的實例,如果這個屬性是非公有的叮称,這里會報IllegalAccessException种玛。
2. 得到某個類的靜態(tài)屬性
Java代碼
? ? public Object getStaticProperty(String className, String fieldName)?
? ? ? ? ? ? ? ? throws Exception {?
? ? ? ? Class ownerClass = Class.forName(className);?
? ? ? ? Field field = ownerClass.getField(fieldName);?
? ? ? ? Object property = field.get(ownerClass);?
? ? ? ? return property;?
? ? }?
Class ownerClass = Class.forName(className) :首先得到這個類的Class。
Field field = ownerClass.getField(fieldName):和上面一樣颅拦,通過Class得到類聲明的屬性蒂誉。
Object property = field.get(ownerClass) :這里和上面有些不同,因為該屬性是靜態(tài)的距帅,所以直接從類的Class里取右锨。
3. 執(zhí)行某對象的方法
Java代碼
? ? public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {?
? ? ? ? Class ownerClass = owner.getClass();?
? ? ? ? Class[] argsClass = new Class[args.length];?
? ? ? ? for (int i = 0, j = args.length; i < j; i++) {?
? ? ? ? ? ? argsClass[i] = args[i].getClass();?
? ? ? ? }?
? ? ? ? ? Method method = ownerClass.getMethod(methodName,argsClass);?
? ? ? ? return method.invoke(owner, args);?
? ? }?
Class owner_class = owner.getClass() :首先還是必須得到這個對象的Class。
5~9行:配置參數的Class數組碌秸,作為尋找Method的條件绍移。
Method method = ownerClass.getMethod(methodName, argsClass):通過methodName和參數的argsClass(方法中的參數類型集合)數組得到要執(zhí)行的Method。
method.invoke(owner, args):執(zhí)行該Method.invoke方法的參數是執(zhí)行這個方法的對象owner讥电,和參數數組args蹂窖,可以這么理解:owner對象中帶有參數args的method方法。返回值是Object恩敌,也既是該方法的返回值瞬测。
4. 執(zhí)行某個類的靜態(tài)方法
Java代碼
? ? public Object invokeStaticMethod(String className, String methodName,?
? ? ? ? ? ? ? ? Object[] args) throws Exception {?
? ? ? ? Class ownerClass = Class.forName(className);?
? ? ? ? Class[] argsClass = new Class[args.length];?
? ? ? ? for (int i = 0, j = args.length; i < j; i++) {?
? ? ? ? ? ? argsClass[i] = args[i].getClass();?
? ? ? ? }?
? ? ? ? Method method = ownerClass.getMethod(methodName,argsClass);?
? ? ? ? return method.invoke(null, args);?
? ? }?
基本的原理和實例3相同,不同點是最后一行纠炮,invoke的一個參數是null月趟,因為這是靜態(tài)方法,不需要借助實例運行恢口。
5. 新建實例
Java代碼
? ? public Object newInstance(String className, Object[] args) throws Exception {?
? ? ? ? Class newoneClass = Class.forName(className);?
? ? ? ? Class[] argsClass = new Class[args.length];?
? ? ? ? for (int i = 0, j = args.length; i < j; i++) {?
? ? ? ? ? ? argsClass[i] = args[i].getClass();?
? ? ? ? }?
? ? ? ? Constructor cons = newoneClass.getConstructor(argsClass);?
? ? ? ? return cons.newInstance(args);?
? ? }?
這里說的方法是執(zhí)行帶參數的構造函數來新建實例的方法孝宗。如果不需要參數,可以直接使用newoneClass.newInstance()來實現耕肩。
Class newoneClass = Class.forName(className):第一步因妇,得到要構造的實例的Class。
第5~第9行:得到參數的Class數組猿诸。
Constructor cons = newoneClass.getConstructor(argsClass):得到構造子婚被。
cons.newInstance(args):新建實例。
6. 判斷是否為某個類的實例
Java代碼
? ? public boolean isInstance(Object obj, Class cls) {?
? ? ? ? return cls.isInstance(obj);?
? ? }?
7. 得到數組中的某個元素
Java代碼
? ? public Object getByArray(Object array, int index) {?
? ? ? ? return Array.get(array,index);?
? ? }?