1. 程式人生 > >9.反射的基本原理

9.反射的基本原理

構造方法 註意 配置 pan 分析 靜態 操作 string類型 pri

1.反射的原理

  * 應用在一些通用性比較高的代碼中

  * 例如後面學到的框架,大多數都是使用反射來實現的

  * 在框架開發中,都是基於配置文件開發

    在配置文件中配置了類,可以通過反射得到類中的所有內容,可以讓類中的某些方法來執行

  * 類中的所有內容:屬性、沒有參數的構造方法、有參數的構造方法、普通方法

  * 畫圖分析反射的原理

      * 首先需要把java文件保存到本地硬盤上 .java

      * 編譯java文件,成.class文件

      * 萬事萬物都是對象,class文件在內存中使用class類表示

      * 當使用反射時候,首先需要獲取到class類,得到這個類之後,就可以得到class文件中的所有內容

      * 屬性通過一個類 Field 表示

      * 構造方法通過一個類 Constructor 表示

      * 普通方法通過一個類 Method類 表示

技術分享圖片

2.實例

Persion類

package Day5;

public class Persion {
    //屬性
    private String id;
    private String name;
    
    //沒有參數的構造方法
    public Persion() {}
    
    //有參數的構造方法
    public Persion(String id , String name) {
        
this.id = id; this.name = name; } //普通方法 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

  (1)獲取class類的三種方式

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Persion.class;
        Class c2 = new Persion().getClass();
        //註意參數為包名+類名,推薦使用這種方式
        Class c3 = Class.forName("Day5.Persion");
    }
}

  (2)操作無參數的構造方法

  @Test
    public void test1() throws Exception   {
        //獲取calss類
        Class c3 = Class.forName("Day5.Persion");
        //獲取persion類的實例(當創建persion實例的時候,無參數的構造方法已經運行了)
        Persion persion = (Persion) c3.newInstance();
        //通過persion實例調用裏面的普通的方法
        persion.setName("張三");
        //我們來查看我們設置的值是否成功
        System.out.println(persion.getName());
    }

  (3)操作有參數的構造方法

  @Test
    public void test2() throws Exception {
        //獲取class類
        Class c3 = Class.forName("Day5.Persion");
        //獲取有參數的構造方法(c3.getConstructors();  獲取所有的構造方法)
        //裏面的參數是使用class形式傳遞的(persion有參的構造方法是String類型)
        //java.lang.reflect.Constructor
        Constructor cs =  c3.getConstructor(String.class,String.class);
        //通過有參數的構造方法獲取persion實例
        Persion persion = (Persion) cs.newInstance("101","張三");
        //輸出我們設置的值
        System.out.println(persion.getId()+" "+persion.getName());
    }

  (4)操作屬性

@Test
    public void test3() throws Exception {
        //獲取class類
        Class c3 = Class.forName("Day5.Persion");
        //獲取persion的實例
        Persion persion = (Persion) c3.newInstance();
        //獲取name屬性
        Field field = c3.getDeclaredField("name");
        //因為我們定義的屬性是私有的,所以不能直接操作,我們設置為可以操作私有屬性
        field.setAccessible(true);
        //設置name的值為張三
        field.set(persion, "張三");
        //輸出name屬性的值
        System.out.println(field.get(persion));
    }

  (5)操作普通方法(如果方法為私用的。需要設置method.setAccessible(true))

    註意:當使用反射操作靜態的方法的時候invokie方法的第一個參數裏面寫一個null

@Test
    public void test4() throws Exception {
        //獲取class類
        Class c3 = Class.forName("Day5.Persion");
        //獲取persion的實例
        Persion persion = (Persion) c3.newInstance();
        //獲取setName普通方法(參數一:方法名     參數二:方法裏面的參數類型)
        Method method = c3.getDeclaredMethod("setName", String.class);
        //通過獲取的setName設置值
        method.invoke(persion, "張三");
        //輸出
        System.out.println(persion.getName());
    }

9.反射的基本原理