Java反射基礎知識
阿新 • • 發佈:2021-02-06
文章目錄
java反射是指在執行狀態中,對於任意一個類都能夠知道這個類所有的屬性和方法, 並且可以呼叫其屬性和方法。這種動態獲取資訊和操作物件方法的功能被稱為反射。 簡單描述:反射可以實現在執行時獲取並操作類的屬性和方法。
1 Class類的使用
1.1 獲取例項的物件
任何一個類都是Class的例項物件,獲取例項的物件有三種方式。
1.1.1 第一種:
任何一個類都有一個隱含的靜態成員變數class:
Class class1 = People.class;
1.1.2 第二種:
已經知道該類的物件,通過類物件的getClass方法:
Peaple people = new People();
Class class2 = people.getClass();
1.1.3 第三種:
使用Class的forName方法:
Class class3 = Class.forName("類的全路徑" );
1.2 通過類的類型別建立該類的物件
通過類的類型別建立該類的物件,前提:有無參構造方法
People people = (People)class3.getInstance();
2 動態載入類
Class.forName("類的全路徑")不僅表示類的類型別,還代表了動態載入類。編譯時載入類為靜態載入類,
執行時載入類為動態載入類。new 建立物件 是靜態載入,在編譯時刻就需要載入所有可能用到的類。通過
動態載入類就可解決該問題。
3 Class類的基本API
3.1 獲取建構函式資訊
- getConstructor(Class…):獲取某個public的建構函式;
- getDeclaredConstructor(Class…):獲取某個建構函式;
- getConstructors():獲取所有public的建構函式;
- getDeclaredConstructors():獲取所有建構函式;
public static void getConstructorsMessage(Object obj){
// 獲取類型別,getClass()方法是native修飾的方法
Class<?> objClass = obj.getClass();
// 獲得所有公有構造方法
Constructor<?>[] constructors = objClass.getConstructors();
// 獲得自己宣告的構造方法
Constructor<?>[] declaredConstructors = objClass.getDeclaredConstructors();
for(Constructor<?> constructor : declaredConstructors){
// 獲得引數型別
Class<?>[] parameterTypes = constructor.getParameterTypes();
for (Class<?> parameterType : parameterTypes){
System.out.println("parameterType = " + parameterType);
}
}
}
3.2 獲取方法資訊
3.2.1 通過類的類型別獲取方法
- Method getMethod(name, Class…):獲取某個public修飾的方法(包括父類);
- Method getDeclaredMethod(name, Class…):獲取當前類的某個方法(不包括父類);
- Method[] getMethods():獲取所有public修飾的方法(包括父類);
- Method[] getDeclaredMethods():獲取當前類的所有方法(不包括父類);
3.2.2 獲取方法資訊
- getName():返回方法名稱;
- getReturnType():返回方法返回值型別,也是一個Class例項;
- getParameterTypes():返回方法的引數型別,是一個Class陣列;
- getModifiers():返回方法的修飾符。
public class ClassUtil {
public static void getMethodMessage(Object obj){
// 獲取類型別,getClass()方法是native修飾的方法
Class<?> objClass = obj.getClass();
// 獲取類的名稱
String className = objClass.getName();
System.out.println("className = " + className);
// 獲取類所有public方法,包括從父類繼承的
Method[] objClassMethods = objClass.getMethods();
System.out.println("objClassMethods = " + Arrays.toString(objClassMethods));
// 獲取該類自己宣告的所有方法
Method[] declaredMethods = objClass.getDeclaredMethods();
for (Method method: declaredMethods) {
// 獲得方法的返回值型別的類型別
Class<?> returnType = method.getReturnType();
// 獲得方法名稱
String methodName = method.getName();
System.out.println("methodName = " + methodName + "returnType = " + returnType);
// 獲取引數型別:引數列表的類型別
Class<?>[] parameterTypes = method.getParameterTypes();
}
}
}
3.3 獲取屬性資訊
3.3.1 類的類型別方法獲取屬性
- Field getField(name):根據欄位名獲取某個public的field(包括父類);
- Field getDeclaredField(name):根據欄位名獲取當前類的某個field(不包括父類);
- Field[] getFields():獲取所有public的field(包括父類);
- Field[] getDeclaredFields():獲取當前類的所有field(不包括父類);
3.3.2 獲取屬性資訊
- getName():返回欄位名稱;
- getType():返回欄位型別,也是一個Class例項;
- getModifiers():返回欄位的修飾符;
public static void getFiledMessage(Object obj) {
// 獲取類型別,getClass()方法是native修飾的方法
Class<?> objClass = obj.getClass();
// Filed類封裝了關於成員變數的操作
// 獲取該類自己宣告的成員變數
Field[] declaredFields = objClass.getDeclaredFields();
for(Field field : declaredFields){
// 獲取成員變數的名稱
String name = field.getName();
// 獲取成員變數的型別
Class<?> type = field.getType();
System.out.println("name = " + name + "type = " + type);
}
}
3.4 繼承關係
- Class getSuperclass():獲取父類型別;
- 使用instanceof操作符判斷一個例項是否是某個型別;
4 方法反射的基本操作
public static void invokeMethod(Object obj)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 獲取類型別,getClass()方法是native修飾的方法
Class<?> objClass = obj.getClass();
// 根據方法名與引數型別獲取方法
Method start = objClass.getMethod("start", Integer.class, String.class);
// 執行方法
Object invoke = start.invoke(obj, 1, "hangzhou");
System.out.println("invoke = " + invoke);
}