無論是身處學校還是步入社會,大家都嘗試過寫作吧,借助寫作也可以提高我們的語言組織能力。那么我們該如何寫一篇較為完美的范文呢?以下是小編為大家收集的優(yōu)秀范文,歡迎大家分享閱讀。
深入理解java的反射效應 java的反射機制和注解原理篇一
要想理解反射的原理,首先要了解什么是類型信息。java讓我們在運行時識別對象和類的信息,主要有2種方式:一種是傳統(tǒng)的rtti,它假定我們在編譯時已經知道了所有的類型信息;另一種是反射機制,它允許我們在運行時發(fā)現(xiàn)和使用類的信息。
理解rtti在java中的工作原理,首先需要知道類型信息在運行時是如何表示的,這是由class對象來完成的,它包含了與類有關的信息。class對象就是用來創(chuàng)建所有“常規(guī)”對象的,java使用class對象來執(zhí)行rtti,即使你正在執(zhí)行的是類似類型轉換這樣的操作。
每個類都會產生一個對應的class對象,文件。所有類都是在對其第一次使用時,動態(tài)加載到jvm的,當程序創(chuàng)建一個對類的靜態(tài)成員的引用時,就會加載這個類。class對象僅在需要的時候才會加載,static初始化是在類加載時進行的。
public class testmain {public static void main(string[] args) {n();}}class xyz {public static string name = "luoxn28";static {n("xyz靜態(tài)塊");}public xyz() {n("xyz構造了");}}
輸出結果為:
類加載器首先會檢查這個類的class對象是否已被加載過,如果尚未加載,文件。
想在運行時使用類型信息,必須獲取對象(比如類base對象)的class對象的引用,使用功能e(“base”)可以實現(xiàn)該目的,或者使用。注意,有一點很有趣,使用功能”.class”來創(chuàng)建class對象的引用時,不會自動初始化該class對象,使用forname()會自動初始化該class對象。為了使用類而做的準備工作一般有以下3個步驟:
加載:由類加載器完成,找到對應的字節(jié)碼,創(chuàng)建一個class對象
鏈接:驗證類中的字節(jié)碼,為靜態(tài)域分配空間
初始化:如果該類有超類,則對其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊
public class base {static int num = 1;static {n("base " + num);}}public class main {public static void main(string[] args) {// 不會初始化靜態(tài)塊class clazz1 = ;n("------");// 會初始化class clazz2 = e("");}}
編譯器將檢查類型向下轉型是否合法,如果不合法將拋出異常。向下轉換類型前,可以使用instanceof判斷。
class base { }class derived extends base { }public class main {public static void main(string[] args) {base base = new derived();if (base instanceof derived) {// 這里可以向下轉換了n("ok");}else {n("not ok");}}}
如果不知道某個對象的確切類型,rtti可以告訴你,但是有一個前提:這個類型在編譯時必須已知,這樣才能使用rtti來識別它。t類庫一起對反射進行了支持,該類庫包含field、method和constructor類,這些類的對象由jvm在啟動時創(chuàng)建,用以表示未知類里對應的成員。這樣的話就可以使用contructor創(chuàng)建新的對象,用get()和set()方法獲取和修改類中與field對象關聯(lián)的`字段,用invoke()方法調用與method對象關聯(lián)的方法。另外,還可以調用getfields()、getmethods()和getconstructors()等許多便利的方法,以返回表示字段、方法、以及構造器對象的數(shù)組,這樣,對象信息可以在運行時被完全確定下來,而在編譯時不需要知道關于類的任何事情。
反射機制并沒有什么神奇之處,當通過反射與一個未知類型的對象打交道時,jvm只是簡單地檢查這個對象,看它屬于哪個特定的類。因此,對于jvm來說必須是可獲取的,要么在本地機器上,要么從網絡獲取。所以對于rtti和反射之間的真正區(qū)別只在于:
rtti,文件
反射,文件
public class person implements serializable {private string name;private int age;// get/set方法}public static void main(string[] args) {person person = new person("luoxn28", 23);class clazz = ss();field[] fields = laredfields();for (field field : fields) {string key = e();propertydescriptor descriptor = new propertydescriptor(key, clazz);method method = dmethod();object value = (person);n(key + ":" + value);}}
以上通過getreadmethod()方法調用類的get函數(shù),可以通過getwritemethod()方法來調用類的set方法。通常來說,我們不需要使用反射工具,但是它們在創(chuàng)建動態(tài)代碼會更有用,反射在java中用來支持其他特性的,例如對象的序列化和javabean等。
代理模式是為了提供額外或不同的操作,而插入的用來替代”實際”對象的對象,這些操作涉及到與”實際”對象的通信,因此代理通常充當中間人角色。java的動態(tài)代理比代理的思想更前進了一步,它可以動態(tài)地創(chuàng)建并代理并動態(tài)地處理對所代理方法的調用。在動態(tài)代理上所做的所有調用都會被重定向到單一的調用處理器上,它的工作是揭示調用的類型并確定相應的策略。以下是一個動態(tài)代理示例:
接口和實現(xiàn)類:
public interface interface {void dosomething();void somethingelse(string arg);}public class realobject implements interface {public void dosomething() {n("dosomething.");}public void somethingelse(string arg) {n("somethingelse " + arg);}}
動態(tài)代理對象處理器:
public class dynamicproxyhandler implements invocationhandler {private object proxyed;public dynamicproxyhandler(object proxyed) {d = proxyed;}@overridepublic object invoke(object proxy, method method, object[] args) throws illegalaccessexception, illegalargumentexception, invocationtargetexception {n("代理工作了.");return (proxyed, args);}}
測試類:
public class main {public static void main(string[] args) {realobject real = new realobject();interface proxy = (interface) xyinstance(ssloader(), new class[] {},new dynamicproxyhandler(real));thing();ingelse("luoxn28");}}
輸出結果如下:
xyinstance()可以創(chuàng)建動態(tài)代理,這個方法需要得到一個類加載器,一個你希望該代理實現(xiàn)的接口列表(不是類或抽象類),以及invocationhandler的一個實現(xiàn)類。動態(tài)代理可以將所有調用重定向到調用處理器,因此通常會調用處理器的構造器傳遞一個”實際”對象的引用,從而將調用處理器在執(zhí)行中介任務時,將請求轉發(fā)。
以上所述是小編給大家介紹的深入理解java反射,希望對大家有所幫助,如果大家有任何疑問請給我們留言,小編會及時回復大家的。在此也非常感謝大家對的支持!
s("content_relate");【深入理解java的反射】相關文章:
1.最新的java容器類的深入理解2.深入理解java事物原理與應用3.java tomcat和激活myeclips的深入理解4.淺談java線程中斷的本質深入理解5.關于java 反射的簡介6.java中反射機制7.java反射機制學習總結8.java使用反射技術示例