Java反射基本概念

反射

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

獲取Class對象的方式

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

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

在這裏插入圖片描述

例子:Java反射獲取私有屬性並修改

關鍵步驟:setAccessible(true)

1、新建一個類,並設置私有屬性值

public class Student {

    private String name = "kobe";

    public String getName() {
        return name;
    }

}

2、新建測試類

import java.lang.reflect.Field;

public class TestSetAccessible {
    public static void main(String[] args) throws Exception{
        Student stu = new Student();
        Class<?> clazz = Student.class;

        // 獲得指定類的屬性
        Field field = clazz.getDeclaredField("name");
        field.setAccessible(true);
        // 更改私有屬性的值
        field.set(stu, "bryant");
        System.out.println(stu.getName());
    }
}

輸出結果:

bryant

反射的用途

  • 反射最重要的用途就是開發各種通用框架,比如在spring中,我們將所有的類Bean交給spring容器管理,無論是XML配置Bean還是註解配置,當我們從容器中獲取Bean來依賴注入時,容器會讀取配置,而配置中給的就是類的信息,spring根據這些信息,需要創建那些Bean,spring就動態的創建這些類。還有在struts2的struts.xml中配置action,也是通過反射調用action。

  • 還有在我們創建數據庫鏈接時,這句代碼
    Class tc = Class.forName(“com.java.dbtest.TestConnection”)
    就是告訴JVM去加載這個類,而加載的過程是在程序執行過程中動態加載的。通過類的全類名讓jvm在服務器中找到並加載這個類,而如果是使用別的數據庫,那就要換一個類了,如果是傳統寫死的方法創建,就要修改原來類的代碼,而對於反射,則只是傳入的參數就變成另一個了而已,可以通過修改配置文件,而不是直接修改代碼。

  • 再比如我們有兩個程序員,一個程序員在寫程序的時候,需要使用第二個程序員所寫的類,但第二個程序員並沒完成他所寫的類。那麼第一個程序員的代碼能否通過編譯呢?這是不能通過編譯的。利用Java反射的機制,就可以讓第一個程序員在沒有得到第二個程序員所寫的類的時候,來完成自身代碼的編譯。只是如果這個類還沒有,獲取時會獲取不到,但不會導致編譯錯誤,更不會導致程序的崩潰。

  • 還有當我們在使用 IDE(如 Eclipse\IDEA)時,當我們輸入一個隊長或者類並向調用它的屬性和方法時,一按 (“.”)點號,編譯器就會自動列出她的屬性或方法,這裏就會用到反射。

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