JAVA反射机制Reflection详解
目錄
反射機(jī)制Reflection
1、靜態(tài) VS 動態(tài)語言
2、Java Reflection
Java反射機(jī)制提供的功能
Java反射優(yōu)點(diǎn)和缺點(diǎn)
3、反射相關(guān)的主要API
4、Class類
5、Java內(nèi)存分析
6、創(chuàng)建運(yùn)行時類的對象
7、有了Class對象,能做什么?
創(chuàng)建類的對象:調(diào)用Class對象的newInstance()方法
思考?難道沒有無參的構(gòu)造器就不能創(chuàng)建對象了嗎?只要在操作的時候明確的調(diào)用類中的構(gòu)造器,并將參數(shù)傳遞進(jìn)去之后,才可以實(shí)例化操作。
步驟如下:
調(diào)用指定的方法
8、setAccessible
9、反射操作泛型
反射機(jī)制Reflection
1、靜態(tài) VS 動態(tài)語言
動態(tài)語言
是一類在運(yùn)行時可以改變其結(jié)構(gòu)的語言:例如新的函數(shù)、對象、甚至代碼可以被引進(jìn),已有的
函數(shù)可以被刪除或是其他結(jié)構(gòu)上的變化。通俗點(diǎn)說就是在運(yùn)行時代碼可以根據(jù)某些條件改變自
身結(jié)構(gòu)。
主要動態(tài)語言:Object-C、C#、JavaScript、PHP、Python等
與動態(tài)語言相對應(yīng)的,運(yùn)行時結(jié)構(gòu)不可變的語言就是靜態(tài)語言。如Java、C、C++。
Java不是動態(tài)語言,但Java可以稱之為“準(zhǔn)動態(tài)語言”。即Java有一定的動態(tài)性,我們可以利用
反射機(jī)制獲得類似動態(tài)語言的特性。Java的動態(tài)性讓編程的時候更加靈活!
2、Java Reflection
Reflection(反射)是Java被視為動態(tài)語言的關(guān)鍵,反射機(jī)制允許程序在執(zhí)行期借助于Reflection API取
得任何類的內(nèi)部信息,并能直接操作任意對象的內(nèi)部屬性及方法。
Class c = Class.forName("java.lang.String")
加載完類之后,在堆內(nèi)存的方法區(qū)中就產(chǎn)生了一個Class類型的對象(一個類只有一個Class對象),這
個對象就包含了完整的類的結(jié)構(gòu)信息。我們可以通過這個對象看到類的結(jié)構(gòu)。這個對象就像一面鏡子,
透過這個鏡子看到類的結(jié)構(gòu),所以,我們形象的稱之為:反射
Java反射機(jī)制提供的功能
在運(yùn)行時判斷任意一個對象所屬的類
在運(yùn)行時構(gòu)造任意一個類的對象
在運(yùn)行時判斷任意一個類所具有的成員變量和方法
在運(yùn)行時獲取泛型信息
在運(yùn)行時調(diào)用任意一個對象的成員變量和方法
在運(yùn)行時處理注解
生成動態(tài)代理
……
Java反射優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn):可以實(shí)現(xiàn)動態(tài)創(chuàng)建對象和編譯,體現(xiàn)出很大的靈活性 !
缺點(diǎn):對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿
足我們的要求。這類操作總是慢于 直接執(zhí)行相同的操作。
3、反射相關(guān)的主要API
java.lang.Class : 代表一個類
java.lang.reflect.Method : 代表類的方法
java.lang.reflect.Field : 代表類的成員變量
java.lang.reflect.Constructor : 代表類的構(gòu)造器
4、Class類
在Object類中定義了該方法,此方法將被所有子類繼承
public final Class getClass();以上的方法返回值的類型是一個Class類,此類是Java反射的源頭,實(shí)際上所謂反射從程序的運(yùn)行結(jié)果來
看也很好理解,即:可以通過對象反射求出類的名稱。
對象照鏡子后可以得到的信息:某個類的屬性、方法和構(gòu)造器、某個類到底實(shí)現(xiàn)了哪些接口。對于每個
類而言,JRE 都為其保留一個不變的 Class 類型的對象。一個 Class 對象包含了特定某個結(jié)構(gòu)
(class/interface/enum/annotation/primitive type/void/[])的有關(guān)信息。
Class 本身也是一個類
Class 對象只能由系統(tǒng)建立對象
一個加載的類在 JVM 中只會有一個Class實(shí)例
一個Class對象對應(yīng)的是一個加載到JVM中的一個.class文件
每個類的實(shí)例都會記得自己是由哪個 Class 實(shí)例所生成
通過Class可以完整地得到一個類中的所有被加載的結(jié)構(gòu)
Class類是Reflection的根源,針對任何你想動態(tài)加載、運(yùn)行的類,唯有先獲得相應(yīng)的Class對象
5、Java內(nèi)存分析
?
6、創(chuàng)建運(yùn)行時類的對象
通過反射獲取運(yùn)行時類的完整結(jié)構(gòu)
Field、Method、Constructor、Superclass、Interface、Annotation
實(shí)現(xiàn)的全部接口
所繼承的父類
全部的構(gòu)造器
全部的方法
全部的Field
注解
。。。
小結(jié)
在實(shí)際的操作中,取得類的信息的操作代碼,并不會經(jīng)常開發(fā)。
一定要熟悉java.lang.reflect包的作用,反射機(jī)制。
7、有了Class對象,能做什么?
創(chuàng)建類的對象:調(diào)用Class對象的newInstance()方法
類必須有一個無參數(shù)的構(gòu)造器。
類的構(gòu)造器的訪問權(quán)限需要足夠
思考?難道沒有無參的構(gòu)造器就不能創(chuàng)建對象了嗎?只要在操作的時候明確的調(diào)用類中的構(gòu)造器,并將參數(shù)傳遞進(jìn)去之后,才可以實(shí)例化操作。
步驟如下:
通過Class類的getDeclaredConstructor(Class … parameterTypes)取得本類的指定形參類型
的構(gòu)造器
向構(gòu)造器的形參中傳遞一個對象數(shù)組進(jìn)去,里面包含了構(gòu)造器中所需的各個參數(shù)。
通過Constructor實(shí)例化對象
調(diào)用指定的方法
通過反射,調(diào)用類中的方法,通過Method類完成。
通過Class類的getMethod(String name,Class…parameterTypes)方法取得一個Method對
象,并設(shè)置此方法操作時所需要的參數(shù)類型。
之后使用Object invoke(Object obj, Object[] args)進(jìn)行調(diào)用,并向方法中傳遞要設(shè)置的obj對
象的參數(shù)信息。
8、setAccessible
Method和Field、Constructor對象都有setAccessible()方法。
setAccessible作用是啟動和禁用訪問安全檢查的開關(guān)。
參數(shù)值為true則指示反射的對象在使用時應(yīng)該取消Java語言訪問檢查。
提高反射的效率。如果代碼中必須用反射,而該句代碼需要頻繁的被調(diào)用,那么請設(shè)置為true。
使得原本無法訪問的私有成員也可以訪問
參數(shù)值為false則指示反射的對象應(yīng)該實(shí)施Java語言訪問檢查
9、反射操作泛型
Java采用泛型擦除的機(jī)制來引入泛型 , Java中的泛型僅僅是給編譯器javac使用的,確保數(shù)據(jù)的安全性
和免去強(qiáng)制類型轉(zhuǎn)換問題 , 但是 , 一旦編譯完成 , 所有和泛型有關(guān)的類型全部擦除
為了通過反射操作這些類型 , Java新增了 ParameterizedType , GenericArrayType , TypeVariable
和 WildcardType 幾種類型來代表不能被歸一到Class類中的類型但是又和原始類型齊名的類型.
ParameterizedType : 表示一種參數(shù)化類型,比如Collection
GenericArrayType : 表示一種元素類型是參數(shù)化類型或者類型變量的數(shù)組類型
TypeVariable : 是各種類型變量的公共父接口
WildcardType : 代表一種通配符類型表達(dá)式
總結(jié)
以上是生活随笔為你收集整理的JAVA反射机制Reflection详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS_综合,全面性增删改查,多条件查询,
- 下一篇: 计算机过程控制系统教材,过程控制系统——