JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
“程序運行時,允許改變程序結構或變量類型,這種語言稱為動態語言”。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。但是JAVA有著一個非常突出的動態相關機制:Reflection,用在Java身上指的是我們可以於運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。
Java反射機制主要相關的類:
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
Java中獲取Class有三種方式(以UserBean類為例):
1、類名.class
UserBean.class
2、對象.getClass();
UserBean userBean = new UserBean();
userBean.getClass();
3、Class.forName()
Class.forName("com.alfred.bean.UserBean");
如果是在同級目錄下可以不加路徑
需要解釋一點就是,java中一切都是對象,我們獲取的Class也是一個對象。基本類型int、float等也會在jvm的內存池像其他類型一樣生成一個Class對象。而數組等組合型數據類型也是會生成一個Class對象的,而且更令人驚訝的是,java中數組的本來面目其實就是某個類。
例如:
Class c1 = int.class;
Class c2 = Double[].class;
通過使用java反射機制可以實現:
1、運行時獲取類結構(包括類名,修飾符,屬性,方法,構造函數,父類,接口等等)
2、運行時調用類公共方法(可以傳遞方法參數)
3、運行時創建類對象
以下是一個java反射機制的實例:
package com.alfred.main; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class Reflection { /** * 打印整個類的結構(包括父子類接口) * @param c Class對象 */ public static void printClassStructure(Class c) { try { // 獲取所有的屬性(不包括父類的) Field[] fs = c.getDeclaredFields(); // 定義可變長的字符串,用來存儲屬性 StringBuffer sb = new StringBuffer(); // 通過追加的方法,將每個屬性拼接到此字符串中 // 最外邊的public定義 sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName()); Class superclass = c.getSuperclass(); if (superclass != null && !superclass.getSimpleName().equals("Object")) { // 不是直接繼承於Object,說明有其他繼承類 printClassStructure(superclass); sb.append(" extends " + superclass.getSimpleName()); } Class[] interfaces = c.getInterfaces(); if (interfaces.length > 0) { sb.append(" implements "); for (int i = 0; i < interfaces.length; i++) { printClassStructure(interfaces[i]); sb.append(((i != 0) ? "," : "") + interfaces[i].getSimpleName()); } } sb.append("{\n"); // 類中的屬性 for (Field field : fs) { sb.append("\t");// 縮進 sb.append(Modifier.toString(field.getModifiers()) + " ");// 獲得屬性的修飾符,例如public,static等等 sb.append(field.getType().getSimpleName() + " "); sb.append(field.getName() + ";\n"); } // 類中的構造方法 Constructor[] declaredConstructors = c.getDeclaredConstructors(); for (Constructor constructor : declaredConstructors) { sb.append("\t"); sb.append(Modifier.toString(constructor.getModifiers()) + " "); sb.append(c.getSimpleName() + "("); Class[] parameterTypes = constructor.getParameterTypes(); for (int i = 0; i < parameterTypes.length; i++) { sb.append(((i != 0) ? "," : "") + parameterTypes[i].getSimpleName() + " arg" + i); } sb.append("){}\n"); } // 類中的方法 Method[] ms = c.getDeclaredMethods(); for (Method method : ms) { sb.append("\t"); sb.append(Modifier.toString(method.getModifiers()) + " "); sb.append(method.getReturnType().getSimpleName() + " "); sb.append(method.getName() + "("); Class<?>[] parameterTypes = method.getParameterTypes(); for (int i = 0; i < parameterTypes.length; i++) { sb.append(((i != 0) ? "," : "") + parameterTypes[i].getSimpleName() + " arg" + i); } sb.append("){}\n"); } sb.append("}"); System.out.println(sb); System.out.println("================================="); } catch (Exception e) { e.printStackTrace(); } } /** * 得到某個對象的公共屬性 * @param owner * @param fieldName * @return 該屬性對象 * @throws Exception */ public static Object getProperty(Object owner, String fieldName) throws Exception { Class ownerClass = owner.getClass(); Field field = ownerClass.getDeclaredField(fieldName); Object property = field.get(owner); return property; } /** * 得到某類的靜態公共屬性 * @param className 類名 * @param fieldName 屬性名 * @return 該屬性對象 * @throws Exception */ public static 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; } /** * 執行某對象方法 * @param owner 對象 * @param methodName 方法名 * @param args 參數 * @return 方法返回值 * @throws Exception */ public static 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); } /** * 執行某類的靜態方法 * @param className 類名 * @param methodName 方法名 * @param args 參數數組 * @return 執行方法返回的結果 * @throws Exception */ public static 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); } /** * 新建實例 * @param className 類名 * @param args 構造函數的參數 * @return 新建的實例 * @throws Exception */ public static Object newInstance(String className, Object[] args) throws Exception { Class newClass = 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 = newClass.getConstructor(argsClass); return cons.newInstance(args); } /** * 是不是某個類的實例 * @param obj 實例 * @param cls 類 * @return 如果 obj 是此類的實例,則返回 true */ public static boolean isInstance(Object obj, Class cls) { return cls.isInstance(obj); } /** * 得到數組中的某個元素 * @param array 數組 * @param index 索引 * @return 返回指定數組對象中索引組件的值 */ public static Object getByArray(Object array, int index) { return Array.get(array, index); } }