047-Java反射

反射:框架設計的靈魂

框架:半成品軟件。可以在框架的基礎上進行軟件開發,簡化編碼。

概述

反射:將類的各個組成部分封裝爲其他對象,這就是反射機制。
好處:
            1. 可以在程序運行過程中,操作這些對象。
            2. 可以解耦,提高程序的可擴展性。

 

 

編譯完成後,.java和.class 都屬於源代碼階段, 程序運行,.class被類加載器加載到內存中時爲Class類對象階段,new出對象後爲Runtime階段。

 

獲取Class對象的方式

 

  • Class.forName("全類名"):將字節碼文件加載進內存,返回Class對象,多用於配置文件,將類名定義在配置文件中。讀取文件加載類。
  • 類名.class:通過類名的屬性class獲取,多用於參數的傳遞
  • 對象.getClass():getClass()方法在Object類中定義着,多用於對象的獲取字節碼的方式

同一個字節碼文件(*.class)在一次程序運行過程中,只會被加載一次,不論通過哪一種方式獲取的Class對象都是同一個。

Class對象功能

獲取功能:
1. 獲取成員變量們

  • Field[] getFields() :獲取所有public修飾的成員變量
  • Field getField(String name)   獲取指定名稱的 public修飾的成員變量
  • Field[] getDeclaredFields()  獲取所有的成員變量,不考慮修飾符
  • Field getDeclaredField(String name)  獲取指定名稱的 public修飾的成員變量,不考慮修飾符

2. 獲取構造方法們

  • Constructor<?>[] getConstructors()  
  • Constructor<T> getConstructor(類<?>... parameterTypes)  
  • Constructor<T> getDeclaredConstructor(類<?>... parameterTypes)  
  • Constructor<?>[] getDeclaredConstructors()  

3. 獲取成員方法們:

  • Method[] getMethods()  
  • Method getMethod(String name, 類<?>... parameterTypes)  
  • Method[] getDeclaredMethods()  
  • Method getDeclaredMethod(String name, 類<?>... parameterTypes)  

4. 獲取全類名    

  • String getName()   Class對象功能:

Field:成員變量
操作:

  • void set(Object obj, Object value)    設置值
  • get(Object obj)  獲取值
  • setAccessible(true):暴力反射,忽略訪問權限修飾符的安全檢查。通常在使用private修飾的變量和方法前,要通過方法對象的該方法,setAccessible(true)  ,將其權限打開。

Constructor:構造方法
創建對象:如果使用空參數構造方法創建對象,操作可以簡化:Class對象的newInstance方法

  • T newInstance(Object... initargs)   

Method:方法對象
執行方法:

  • Object invoke(Object obj, Object... args)  

 獲取方法名稱:

  • String getName:獲取方法名

demo

需求:寫一個"框架",不能改變該類的任何代碼的前提下,可以幫我們創建任意類的對象,並且執行其中任意方法
 實現:
                1. 配置文件
                2. 反射
步驟:
                1. 將需要創建的對象的全類名和需要執行的方法定義在配置文件中
                2. 在程序中加載讀取配置文件
                3. 使用反射技術來加載類文件進內存
                4. 創建對象
                5. 執行方法

public class Person {
    private String name;
    private int age;

    public String a;
    protected String b;
    String c;
    private String d;


    public Person() {
    }

    public Person(String name, int age) {

        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }


    public void eat(){
        System.out.println("eat...");
    }

    public void eat(String food){
        System.out.println("eat..."+food);
    }
}

配置文件

className=cn.hello.Student
methodName=eat

反射

public static void main(String[] args) throws Exception {
       
        //1.加載配置文件
        //1.1創建Properties對象
        Properties pro = new Properties();
        //1.2加載配置文件,轉換爲一個集合
        //1.2.1獲取class目錄下的配置文件
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        pro.load(is);

        //2.獲取配置文件中定義的數據
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");

        //3.加載該類進內存
        Class cls = Class.forName(className);
        //4.創建對象
        Object obj = cls.newInstance();
        //5.獲取方法對象
        Method method = cls.getMethod(methodName);
        //6.執行方法
        method.invoke(obj);


    }

執行結果
eat...

 

感謝關注

    加油啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章