【Java从入门到头秃专栏 8】语法篇(七) :反射 动态代理 注解
目錄
1 反射機制
2 反射的應(yīng)用:動態(tài)代理?
3?注解
1 反射機制
????????反射機制(Reflect Machanism),是指在程序運行期間借助Reflect API獲取任何類的內(nèi)部信息,并能直接操作對象的內(nèi)部屬性以及方法,Java本身而言是靜態(tài)語言但是由于Java反射機制的存在又被人們視為是動態(tài)語言。動態(tài)語言就是一類在運行時可以改變其結(jié)構(gòu)的語言,反之而言的就是靜態(tài)語言概念。
????????類被加載完成之后,在堆內(nèi)存的方法區(qū)中就產(chǎn)生了一個Class類型的對象,這個對象就包含了完整的類的結(jié)構(gòu)信息,我們可以通過這個對象看到類的結(jié)構(gòu)。這個對象就像是一面鏡子,透過這個鏡子看到類的結(jié)構(gòu),所以這個過程被形象的稱為是反射。
????????Java提供了一個類java.lang.Class,通過類名.class獲取這個類編譯之后的class文件對象,再通過這個class對象解析得到這個類的所有成分包括:構(gòu)造器對象(Constructor)、成員變量對象(Field)、成員方法對象(Method)。
反射技術(shù)第一步:獲取Class類對象
一?:?類名.class 二?:?對象.getClass() 三?:?Class.forName("類的全限名")?獲取class對象的名稱
反射技術(shù)第二步:獲取類成分
獲取構(gòu)造器對象:
?? 在按照參數(shù)匹配構(gòu)造器的時候,參數(shù)的先后順序唯一固定一個構(gòu)造器,一般都是使用帶有declared的方法,不加declared的方法功能太差只能獲取public方法。?
通過構(gòu)造器對象創(chuàng)建對象:
?? 如果構(gòu)造器被私有化了的話,也就是說構(gòu)造器被private修飾了,需要使用構(gòu)造器對象名.setAccessible(true)暴力打開私有構(gòu)造器的權(quán)限
獲取變量對象:
獲取
使用變量對象取值賦值?
獲取方法對象:
獲取方法對象:
?使用方法對象執(zhí)行方法:
總結(jié)
第一步,獲取class類對象
第二步,獲取構(gòu)造器對象去new一個對象?
第三步,通過對象可以設(shè)置對象的變量值或者調(diào)用對象中的方法
獲取成員變量并取值賦值?
調(diào)用方法
??
?? 反射不僅可以破壞面向?qū)ο蟮姆庋b性(暴力反射),還可以破壞泛型的約束性,具體原因是泛型是在編譯階段的約束,在編譯完成運行時會被擦除泛型約束此時就可以無視泛型約束了,而反射就是在運行時改變操作對象結(jié)構(gòu)的一種機制,于是可以使用反射來破壞泛型的約束性。
反射綜合案例
2 反射的應(yīng)用:動態(tài)代理?
什么叫做代理設(shè)計模式?
? ? ? ? 代理就是使用一個代理將對象包裝起來,然后使用該代理對象取代原始對象,任何對于原對象的調(diào)用都要經(jīng)過代理實現(xiàn),代理對象決定了是否以及何時將方法調(diào)用轉(zhuǎn)到原始對象上去。其中代理模式包括兩種:靜態(tài)代理、動態(tài)代理。
靜態(tài)代理:
? ? ? ? 靜態(tài)代理就是代理類和目標(biāo)對象的類都是在編譯期間就確定下來的,不利于程序的擴展,同時每一個代理類都只能為一個接口所服務(wù),這樣一來程序的開發(fā)中必然會產(chǎn)生過多的代理。
第一步:定一個共用接口
?第二步:定義一個被代理類實現(xiàn)共用接口
第二步:定義一個代理類實現(xiàn)共用接口?
第四步:創(chuàng)建代理類對象并調(diào)用他的方法,在代理類方法定義的時候會被引用代理對象調(diào)用被代理類方法,具體何時引用被代理對象要取決于代理類的方法何時引用,所以說代理對象決定了是否以及何時將方法調(diào)用轉(zhuǎn)到原始對象上去
動態(tài)代理:
? ? ? ? 動態(tài)代理指的是客戶通過代理類來調(diào)用其他對象的方法,并且是在程序運行時根據(jù)需要動態(tài)創(chuàng)建目標(biāo)類的代理對象。相較于靜態(tài)代理,動態(tài)代理將抽象角色(接口)中聲明的所有方法都轉(zhuǎn)移到處理器的一個集中方法中進行處理,這樣一來我們就可以更加靈活和統(tǒng)一的處理中多方法。
第一步:創(chuàng)建一個共用接口
第二步:定義一個被代理類實現(xiàn)共用接口?
第三步:定義一個代理工廠類用于實現(xiàn)創(chuàng)造代理類的功能,代理工廠類不直接實現(xiàn)共用接口,而是利用反射實現(xiàn)與被代理類一樣的接口,代理類調(diào)用被代理類的同名方法要通過handler對象實現(xiàn),handler對象則是實現(xiàn)了InvocationHandler接口的類創(chuàng)建(new)出來的,這個類底層重寫了invoke方法使用反射去調(diào)用被代理類的同名方法
代理工廠
?實現(xiàn)了InvocationHandler接口的類
第四步:創(chuàng)建代理類對象并調(diào)用他的方法,進而調(diào)用被代理類的方法
??
?? 這個代理工廠不只可以代理被代理類siChuanPeople類,還可以代理上個靜態(tài)代理案例中的被代理類HxekClothFactory類,因為使用了反射,所以代理工廠可以動態(tài)的創(chuàng)建所需要的代理類,而不需要用一個創(chuàng)一個
??? 動態(tài)代理只需要理解第三步的具體步驟即可,其他三步與靜態(tài)代理的寫法一樣。
3?注解
? ? ? ? 注解(Annotation)實際上就是代碼里的一些特殊標(biāo)記,這些標(biāo)記可以在編譯、類加載、類運行的時候被讀取,并執(zhí)行相應(yīng)的處理。注解可以想修飾符一樣使用,用于修飾包、類、構(gòu)造器、方法、成員變量、參數(shù)、局部變量的聲明,這些信息被保存在Annation的鍵值對"name=value"中。
? ? ? ? Java SE階段使用的注解比較少,主要是未來框架的學(xué)習(xí)注解會被頻繁的使用,框架=注解+反射+設(shè)計模式。
JDK中內(nèi)置的三個基本注解:
@Override
????????@Override注解就是在繼承父類時可能會需要重寫父類中的方法,還有就是實現(xiàn)一個接口必須重寫接口中的抽象方法。只要是重寫方法的時候就可以使用@Override注解,@Override注解的作用是:對重寫的方法規(guī)范化,一般來說重寫方法需要做到方法的聲明和參數(shù)列表相同方法體可以不同,凡是重寫方法時沒有遵守規(guī)范@Override注解就會報紅,說明重寫方法失敗
?@Deprecated?
?????????@Deprecated????注解表示其所修飾的元素(類、方法……)已經(jīng)過時,雖然不影響該元素的繼續(xù)使用,但是建議最好還是不使用。
過時比較多的當(dāng)屬Date類,以下注解就表明下面的構(gòu)造器已經(jīng)過時,不推薦使用
@SuppressWarnings
????????@SuppressWarnings注解用于抑制編譯器警告,比如說定義一個變量但是并沒有在下文中對這個變量進行引用,這是就會在編譯器也就是IDEA右邊報一個警告,警告不會影響代碼的運行。
加上@SuppressWarnings注解之后這個警告就會消失,哪怕這個變量依然沒有在下面進行引用,此時編譯器右邊沒有了黃色警告
? ? ? ? 元注解就是用于注解(修飾)其他注解的注解
JDK中內(nèi)置的四個元注解:
@Retention
????????@Retention注解用于指定被修飾注解的生命周期。注解中包含了一個RetentionPolicy類型(枚舉類)的成員變量,有以下三種取值
- RetentionPolicy.SOURCE:在源文件中有效,編譯階段丟棄不會在編譯之后的.class文件中存在的
- RetentionPolicy.CLASS:在class文件中有效,保存在編譯之后的.class文件中不會在運行時進行加載。注解上不聲明@Retention的話默認就是取這個值
- RetentionPolicy.RUNTIME:在運行時依然有效,也就是說可以使用反射進行成分的獲取……
@Target
????????@Target注解用于指定被修飾的注解能用于修飾哪些程序元素。注解中也定義了一個枚舉類,里面包含以下值
- TYPE:類、接口(包括注釋類型)或枚舉聲明,
- FIELD:字段聲明(包括枚舉常量)
- METHOD:方法聲明
- PARAMETER:正式的參數(shù)聲明
- CONSTRUCTOR:構(gòu)造函數(shù)聲明
- LOCAL_VARIABLE:局部變量聲明,
- ANNOTATION_TYPE:注釋類型聲明
- PACKAGE:包聲明
- TYPE_PARAMETER:類型參數(shù)聲明
- TYPE_USE:類型的使用
@Documented
????????@Documented注解指定被修飾的注解將會在編譯時被javadoc工具提取成為文檔。也就是說經(jīng)過javadoc編譯之后的class文件中依然會保留這個注解,正常情況下經(jīng)過編譯之后的.class文件不會保留注解。
@Inherited
????????@Inherited注解指定被修飾的注解將具有繼承性。也就是說,當(dāng)一個注解加上?@Inherited修飾之后,被這個注解修飾的類的子類也同時被這個注解所修飾了(繼承性)。
總結(jié)
以上是生活随笔為你收集整理的【Java从入门到头秃专栏 8】语法篇(七) :反射 动态代理 注解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 凯迪拉克XT5后排空间大吗?
- 下一篇: Linux Unbunt 安装显卡驱动
