java反射

1 什么是反射

Java反射機(jī)制是在運(yùn)行狀態(tài)中

對于任意一個(gè)類,都能知道這個(gè)類的所以屬性和方法;

對于任何一個(gè)對象,都能夠調(diào)用它的任何一個(gè)方法和屬性;

這樣動(dòng)態(tài)獲取新的以及動(dòng)態(tài)調(diào)用對象方法的功能就叫做反射

2Class類

Class可以說是反射能夠?qū)崿F(xiàn)的基礎(chǔ)

class關(guān)鍵字是在聲明java類時(shí)使用的;而Class 是java JDK提供的一個(gè)類,完整路徑為 java.lang.Class

對于每一種類,Java虛擬機(jī)都會(huì)初始化出一個(gè)Class類型的實(shí)例,每當(dāng)我們編寫并且編譯一個(gè)新創(chuàng)建的類就會(huì)產(chǎn)生一個(gè)對應(yīng)Class對象,并且這個(gè)Class對象會(huì)被保存在同名.class文件里。

當(dāng)我們new一個(gè)新對象或者引用靜態(tài)成員變量時(shí),Java虛擬機(jī)(JVM)中的類加載器系統(tǒng)會(huì)將對應(yīng)Class對象加載到JVM中,然后JVM再根據(jù)這個(gè)類型信息相關(guān)的Class對象創(chuàng)建我們需要實(shí)例對象或者提供靜態(tài)變量的引用值。

構(gòu)造器是私有的,只有JVM才可以調(diào)用這個(gè)構(gòu)造函數(shù)創(chuàng)建Class的對象

每個(gè)class(注意class是小寫,代表普通類)類,無論創(chuàng)建多少個(gè)實(shí)例對象,在JVM中都對應(yīng)同一個(gè)Class對象。

Class是反射能夠?qū)崿F(xiàn)的基礎(chǔ)的另一個(gè)原因是:Java反射包java.lang.reflect中的所有類都沒有public構(gòu)造方法,要想獲得這些類實(shí)例,只能通過Class類獲取。所以說如果想使用反射,必須得獲得Class對象。

3 反射缺點(diǎn)

性能問題。因?yàn)榉瓷涫窃?b>運(yùn)行時(shí)而不是在編譯時(shí),所有不會(huì)利用到編譯優(yōu)化,同時(shí)因?yàn)槭莿?dòng)態(tài)生成,因此,反射操作的效率要比那些非反射操作低得多。

安全問題。使用反射技術(shù)要求程序必須在一個(gè)沒有安全限制的環(huán)境中運(yùn)行。如果一個(gè)程序必須在有安全限制的環(huán)境中運(yùn)行,如Applet,那么這就是個(gè)問題了。

代碼問題。由于反射允許代碼執(zhí)行一些在正常情況下不被允許的操作(比如訪問私有的屬性和方法),所以使用反射可能會(huì)導(dǎo)致意料之外的副作用--代碼有功能上的錯(cuò)誤,降低可移植性。反射代碼破壞了抽象性,因此當(dāng)平臺(tái)發(fā)生改變的時(shí)候,代碼的行為就有可能也隨著變化。

作者:凱玲之戀

鏈接:http://www.itdecent.cn/p/10c29883eac1

來源:簡書

簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。



1獲取class對象

三種方式獲取Class對象:

Object類中的getClass方法。這也是最常見的產(chǎn)生Class對象的方法。想要用這種方式,必須要明確具體的類,并創(chuàng)建對象,麻煩。

Person p =newPerson();

Classclazz = p.getClass();

直接獲取某一個(gè)對象的class.任何數(shù)據(jù)類型都具備一個(gè)靜態(tài)的屬性.class來獲取其對應(yīng)的class對象。相對簡單,但還是要明確用到的類中的靜態(tài)成員。還是不夠擴(kuò)展

Classclazz = Person.class;

使用Class類中的forName靜態(tài)方法只要通過給定的類的字符串名稱就可以獲取該類,更為擴(kuò)展

.但是這里的className**需要類的完全限定名**,因?yàn)樗亲址?,和?dǎo)沒導(dǎo)包沒任何關(guān)系

Class clazz = Class.forName("com.example.hgx.Person");//得添加異常ClassNotFoundException



2反射構(gòu)造對象

?1創(chuàng)建不需要構(gòu)造參數(shù)的對象

通過class對象的newInstance生成對象。

Person p =newPerson();

Strint className ="com.example.hgx.Person";

Class clazz = Class.forName(className);

Objectobj = clazz.newInstance();

2創(chuàng)建需要構(gòu)造參數(shù)的對象

這時(shí)要通過Class對象獲取指定的Constructor對象,再調(diào)用Constructor對象的newInstance()方法來創(chuàng)建實(shí)例。

//獲取Person類帶一個(gè)(String,int)參數(shù)的構(gòu)造器

Strint className ="com.example.hgx.Person";

Class clazz = Class.forName(className);

Constructor constructor = clazz.getConstructor(String.class,int.class);

Object obj = constructor.newInstance("小明",24);



3反射獲取成員變量

getField: 訪問公有的成員變量

getDeclaredField:所有已聲明的成員變量。但不能得到其父類的成員變量

Strint className ="com.example.hgx.Person";

Class clazz = Class.forName(className);

Object obj = clazz.newInstance();//訪問public字段Field field = clazz.getField("name");

field.set(obj,"小明");

Object o = field.get(obj);//訪問private字段,要取消權(quán)限檢查.暴力訪問

Field field1 =clazz.getDeclaredField("age");

field1.setAccessible(true);

field1.set(obj,24);

Object o1 = field1.get(obj);


反射方式獲取方法

獲取某個(gè)Class對象的方法集合,主要有以下幾個(gè)方法:

-getDeclaredMethods()方法返回類或接口聲明的所有方法,包括公共、保護(hù)、默認(rèn)(包)訪問和私有方法,但不包括繼承的方法。

-getMethods()方法返回某個(gè)類的所有公用(public)方法,包括其繼承類的公用方法。

-getMethod方法返回一個(gè)特定的方法,其中第一個(gè)參數(shù)為方法名稱,后面的參數(shù)為方法的參數(shù)對應(yīng)Class的對象

Class clazz = Class.forName("com.example.hgx.Person");

Method[] methods = clazz.getMethods();//獲得公有方法

for(Method method: methods){ System.out.println(method);}

Method[] all_methods = clazz.getDeclaredMethods();//只獲取本類中的所有方法,包含私有//調(diào)用方法Method method1 = clazz.getMethod("show",null);

//Person中的show()方法,空參

Object obj = clazz.newInstance();method1.invoke(obj,null);

//調(diào)用帶參方法

Method method = clazz.getMethod("paramMethod",String.class,int.class);

Object obj1 = clazz.newInstance();

method.invoke(obj1,"小明",24);


invoke方法的參數(shù),一個(gè)是Object類型,也就是調(diào)用該方法的對象,


原作者鏈接:JAVA反射調(diào)用詳解 - CSDN博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 反射機(jī)制 如何創(chuàng)建Class的實(shí)例 1、過程:源文件經(jīng)過編譯(javac.exe)以后,得到一個(gè)或多個(gè).class...
    _簡書閱讀 300評論 0 0
  • 1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以讓我們在運(yùn)行時(shí)獲取類的函數(shù)、...
    Ten_Minutes閱讀 582評論 0 4
  • 詳解Java反射機(jī)制(Reflection) 反射機(jī)制的作用 JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能...
    顏洛濱閱讀 1,060評論 0 2
  • 反射 (reflective)是可以在運(yùn)行時(shí)加載、使用編譯期間完全未知的類。 程序在運(yùn)行狀態(tài)中,可以動(dòng)態(tài)加載一個(gè)只...
    n油炸小朋友閱讀 292評論 1 0
  • 什么是java反射: JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一...
    樂百事52淑熙閱讀 381評論 0 0

友情鏈接更多精彩內(nèi)容