理解java中反射,區別Class.forName(),Class.forName().instance() ,new

先了解一下反射(這玩意着實讓我理解了好久啊)博文參考(http://blog.csdn.net/cookieweb/article/details/7056277)java

先了解一些基本的概念:運行時,編譯時,編譯型,解釋型,類加載器,動態加載類 
什麼是編譯?將原程序翻譯成計算機語言,就是二進制代碼,在java中是將.java文件也就是源程序翻譯成.class的字節碼 
什麼是編譯時?將原程序翻譯成計算機語言的過程當中,將.java翻譯爲.class文件的過程 
什麼是運行時?就是在啓動這個程序的時候,在java中是,類加載器加載.class文件,並交給jvm處理 
什麼是編譯型語言?將原程序一次性所有轉換爲二進制代碼,而後執行程序 
什麼是解釋型語言?轉換一句,執行一句,java是既編譯又解釋的語言 
編譯型語言和解釋型語言的區別:編譯型語言效率高,依賴於編譯器,可是跨平臺差,解釋型的效率低,依賴於解釋器,但跨平臺強 
什麼是類加載器?類加載器就是JVM中的類裝載器,做用就是將編譯好的.class字節碼運到檢查器進行安全檢查的,檢查經過後開始解釋執行 
什麼是運行時動態加載類? 
反射就是能夠將一個程序(類)在運行的時候得到該程序(類)的信息的機制,也就是得到在編譯期不可能得到的類的信息,由於這些信息是保存在Class對象中的,而這個Class對象是在程序運行時動態加載的 
它 就是能夠在程序運行的時候動態裝載類,查看類的信息,生成對象,或操做生成對象。類在運行的時候,能夠獲得該類的信息,而且 能夠動態的修改這些信息。class對象是在運行的時候產生的,經過class對象操做類的信息是在運行時進行的,當運行 程序的時候,類加載器會加載真正須要的類,什麼是真正須要的呢?就是該類真正起做用,如:有該類的對象實例,或該類調用了靜態方法屬性等
web

過程以下:安全

那麼如何實現反射呢cookie

獲得Class對象
Class類 
       要正確使用Java反射機制就得使用java.lang.Class這個類。它是Java反射機制的起源。當一個類被加載之後,Java虛擬機就會自動產 生一個Class對象。經過這個Class對象咱們就能得到加載到虛擬機當中這個Class對象對應的方法、成員以及構造方法的聲明和定義等信息。
三種方式獲得Class對象: 
1.調用對象的getClass方法,返回該對象的Class對象 
2.Class.forName(「類的完整名字」);有個受查異常 //重要,能夠在類不肯定的狀況下實例化Class,最靈活
jvm

這個方法內部默認調用Class.forName("A",true,this.getClass().getClassLoader());this

true:是否實例化該類,也就是說實際上調用Class.forName(「類的完整名字」)加載類時執行初始化spa

this.getClass().getClassLoader()調用類加載器.net

 

 

 

 

能夠看到static塊實際上是在初始化後執行的線程

若是調用Class.forName("A",false,this.getClass().getClassLoader());翻譯

就會發現只加載不初始化static塊沒有執行,什麼沒有輸出,因此網上不少說靜態塊代碼在類加載時執行不許確的,其實仍是在初始化後執行

須要補充的是:Class.forName("完整類名").newInstance();的用法至關於直接new();
3.Class c=類名.class

---------------------------------------------------------------------------------

Class.forName()加載一個類,返回的該類的類名

newInstance()方法能夠建立一個Class對象的實例,使用該方法實例化一個類時該類必須已經被加載了

new關鍵字實例化一個類時先加載再實例化

獲取類名:(請無視個人包名啊,懶得改了啊啊啊)

 

三種方法均可以獲取。這裏要注意的是A中的構造方法值執行了一次,說明類A只加載了一次。

也就是說程序在運行時JVM先檢查類是否已加載,若是已加載就不在加載第二次。

Class類應用:

這裏介紹一個Constructor類,該類的對象能夠經過Class中getConstructor得到,用於獲取構造方法建立對象

上面的類A不變,修改Test類以下:

能夠看到獲取到了類A中有參的構造方法

獲取類的結構:

這裏須要主要的是隻執行了靜態初始化塊中的內容,應爲只加載了類可是沒有實例化,static塊是跟隨類加載時執行的。

獲取類的所有方法:

這裏我在類A里加了個AA()方法

Test類

能夠看到AA()方法和一些其餘ang裏面的方法(報錯的線程錯誤無視掉好了)

 

取得類中的所有屬性:用到Field類

getDeclaredFielsd()方法能夠獲取所有屬性,getFields()只能獲取公共屬性

我先在類A中加入一些簡單的屬性

Test類

 

看到類A中的屬性都打印出來了。

 

OK了,相似的還能夠獲取屬性的值,類的父類和實現的接口·····當須要時查一下API就能夠了,比較簡單,這裏就不一一列舉了。

相關文章
相關標籤/搜索