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);
}
}