天天看點

Java的反射機制API使用及實作

文章目錄

    • 概述
    • 反射的實作OR擷取Class對象的方式
    • 反射API
      • 擷取類的構造方法的Constructor對象(數組)
      • 擷取類成員變量的Field對象(數組)
      • 類的方法的Method對象(數組)
      • 類的其他資訊

概述

一般在執行個體化對象時,必須要知道類名才可以執行個體化它的對象,這樣我們在應用方面就會受到限制,反射技術,讓我們不知道這個類的類名就可以執行個體化它的對象。

  • java程式在運作時可以獲得任何一個類的位元組碼資訊,包括類的修飾符(public,static等),基類(超類,父類),實作的接口,字段和方法等資訊.
  • java程式在運作時可以根據位元組碼資訊來建立該類的執行個體對象,改變對象的字段内容和調用對象方法.

這樣的機制就叫反射技術。允許程式在運作過程中取得任何一個已知名稱的類的内部資訊.

将類的各個組成部分封裝為其他對象,

  1. 可以在程式運作過程中,操作這些對象。
  2. 可以解耦,提高程式的可擴充性

通過反射機制,我們可以在運作期間擷取對象的類型資訊。利用這一點我們可以實作工廠模式和代理模式等設計模式

反射的實作OR擷取Class對象的方式

  1. Class.forName("全類名")

    :将位元組碼檔案加載進記憶體,傳回Class對象
    1. 多用于配置檔案,将類名定義在配置檔案中。讀取檔案,加載類
  2. 類名.class

    :通過類名的屬性class擷取,多用于參數的傳遞
  3. 對象.getClass()

    :·

    getClass()

    方法在Object類中定義着。.多用于對象的擷取位元組碼的方式
  4. 通過類加載器實作,

    getClassLoader()

結論:

同一個位元組碼檔案(*.class)在一次程式運作過程中,隻會被加載一次,不論通過哪一種方式擷取的Class對象都是同一個。

package reflect;
public class JavaClass {
    //成員變量
    public String name;
    public Integer id;

    //構造方法
    public JavaClass() {}
    //成員方法
    public void sayHello(){}

    public JavaClass(String name, Integer id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}
           
public class ClassFor {
    @Test
    public void testJavaClass() throws ClassNotFoundException {
        Class aClass = Class.forName("reflect.JavaClass");
        System.out.println("Class.forName:"+aClass);

        Class<JavaClass> javaClassClass = JavaClass.class;
        System.out.println("className.class:"+javaClassClass);

        JavaClass javaClass = new JavaClass();
        Class<? extends JavaClass> aClass1 = javaClass.getClass();
        System.out.println("Object.getClass:"+aClass1);
        Field[] fields = javaClassClass.getFields();
        Arrays.stream(fields).forEach(System.out::println);
    }
}
           

運作結果

Java的反射機制API使用及實作

反射API

反射API位于java.lang.reflect包中.主要包括以下幾類:

擷取類的構造方法的Constructor對象(數組)

  • Constructor

    類:用來描述一個類的構造方法
  • Field

    類:用來描述一個類的成員變量
  • Method

    類:用來描述一個類的方法.
  • Modifer

    類:用來描述類内各元素的修飾符
  • Array

    :用來對數組進行操作.

擷取類成員變量的Field對象(數組)

Field[] getDeclaredFields()

:傳回已加載類聲明的所有成員變量的Field對象數組,不包括從父類繼承的成員變量.

Field getDeclaredField(String name)

:傳回已加載類聲明的所有成員變量的Field對象,不包括從父類繼承的成員變量,參數name指定成員變量的名稱.

Field[] getFields()

:傳回已加載類聲明的所有public型的成員變量的Field對象數組,包括從父類繼承的成員變量

Field getField(String name)

:傳回已加載類聲明的所有成員變量的Field對象,包括從父類繼承的成員變量,參數name指定成員變量的名稱.

類的方法的Method對象(數組)

Method[] getDeclaredMethods()

:傳回已加載類聲明的所有方法的Method對象數組,不包括從父類繼承的方法.

Method getDeclaredMethod(String name,Class[] paramTypes):

傳回已加載類聲明的所有方法的Method對象,不包括從父類繼承的方法,參數name指定方法的名稱,參數paramTypes指定方法的參數類型.

Method[] getMethods()

:傳回已加載類聲明的所有方法的Method對象數組,包括從父類繼承的方法.

Method getMethod(String name,Class[] paramTypes)

:傳回已加載類聲明的所有方法的Method對象,包括從父類繼承的方法,參數name指定方法的名稱,參數paramTypes指定方法的參數類型

類的其他資訊

int getModifiers()

:傳回已加載類的修飾符的整形辨別值.

Package getPackage()

:傳回已加載類的包名

Class getSuperclass()

:傳回已加載類的父類的Class執行個體.

Class [] getInterfaces()

:傳回已加載類實作的接口的Class對象數組.

boolean isInterface()

:傳回已加載類是否是接口.