反射的本質
- Java在執行時能夠獲得或判斷某個物件的型別資訊
- RTTI有一條前提就是某個物件的型別資訊在編譯時必須已知。RTTI的實質就是編譯器在遍歷檢查程式碼時偷偷將型別資訊記錄下來並儲存,以在執行時能夠獲得當編寫完某個.java檔案,並編譯之後,就會產生一個Class物件,由編譯器偷偷的把這個class物件儲存在編譯後的.class檔案中,當這個.class檔案被載入到記憶體之後,隨之會在記憶體中建立這個Class物件了。所以,獲得class物件的前提是能獲得類編譯後的.class檔案。且class物件的功能強大,方法眾多:Class.getInterfaces()、Class.getSuperclass()、Class.getName()、Class.isInterface()等等,能用來獲得很多資訊
- RTTI與反射在最底層的思想上是很類似的,本質的區別在於:對RRTI,編譯器在編譯時開啟和檢查.class檔案,而對反射來說,.class檔案在編譯時是不可獲取的,在執行時未知物件已經來了再去開啟和檢查.class檔案
- 反射機制使得java能夠建立一個在編譯時完全未知的物件。反射在Java中用來支援其他特性的,例如物件的序列化和JavaBean
Class物件
Class物件是進行反射操作的入口,所以首先必須獲得Class物件。除了通過例項獲取外,Class物件主要由以下幾種方法獲得:
- 通過類載入器載入class檔案
Class<?> clazz = Thread.currentThread().getContextClassLoader().
loadClass("com.takumiCX.reflect.ClassTest");
- 通過靜態方法Class.forName()獲取,需要傳入類的全限定名字串作引數(在獲得class物件的同時會引起類的初始化)
Class<?> clazz = Class.forName("com.takumiCX.reflect.ClassTest");
- 通過類.class獲得類的Class物件
Class<ClassTest> clazz = ClassTest.class;
Spring IOC反射機制
- 找到並加裝配置
- 解析配置檔案中的bean元素,並識別id和class
- 通過反射(Class.forName().newInstance())建立這個bean的例項
- 將id作為key、例項作為value存放進Spring容器中
- getBean取出例項