1. 程式人生 > 其它 >Java反射基礎知識

Java反射基礎知識

技術標籤:# 反射java反射後端class

文章目錄

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