先了解一下反射(這玩意着實讓我理解了好久啊)博文參考(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就能夠了,比較簡單,這裏就不一一列舉了。