反射是結(jié)構(gòu)規(guī)劃的靈魂,只有學(xué)好了反射,才干規(guī)劃出好的結(jié)構(gòu)
一.反射的概述
Java反射機(jī)制是在運(yùn)轉(zhuǎn)狀況中,關(guān)于恣意一個類,都能夠知道這個類的一切特點(diǎn)和辦法;關(guān)于恣意一個目標(biāo),都能夠調(diào)用它的恣意辦法和特點(diǎn);這種動態(tài)獲取信息以及動態(tài)調(diào)用目標(biāo)辦法的功能便是Java言語的反射機(jī)制.簡略來說,便是反射能夠協(xié)助咱們在動態(tài)運(yùn)轉(zhuǎn)的時分,關(guān)于恣意一個類,能夠取得其一切辦法,一切的變量(是一切的!包含私有!)
反射的效果
獲取某些類的一些變量,調(diào)用某些類的私有辦法.(舉個栗子,例如在Android開發(fā)中咱們能夠用來敞開WiFi熱點(diǎn),調(diào)用WifiManager中的setWifiApEnabled()辦法)
添加代碼的靈活性.(許多干流結(jié)構(gòu)都運(yùn)用了反射技能,像ssm結(jié)構(gòu)都采用兩種技能xml做配置文件+反射技能)
而咱們要想運(yùn)用反射,就要對反射的常用目標(biāo)有個根本了解
Class
Class類的實(shí)例表明正在運(yùn)轉(zhuǎn)的Java應(yīng)用程序中的類和接口
Constructor
關(guān)于類的單個結(jié)構(gòu)辦法的信息以及對它的拜訪權(quán)限
Field
Field供給有關(guān)類或接口的單個字段的信息,以及對它的動態(tài)拜訪權(quán)限.
Method
Method供給關(guān)于類或接口上單獨(dú)某個辦法的信息
反射在內(nèi)存中的姿態(tài)大約長這樣
在這兒刺進(jìn)圖片描繪
這是一個簡略的Animal類,這個Animal.java文件,想要被履行的話,首先會被編譯成Animal.class文件.而Animal.class想要被履行的話,就會被類加載器加載到JVM中履行,JVM就會將它加載到內(nèi)存,而加載之后,咱們的字節(jié)碼文件Animal.class在內(nèi)存中也會有一個目標(biāo)的表明,別忘了Java言語有句話咋說的,”萬事萬物,皆為目標(biāo)”.而.class文件在內(nèi)存中的目標(biāo)便是Class目標(biāo),所以說取得了Class,才干取得它的結(jié)構(gòu)辦法,特點(diǎn)以及辦法,相對應(yīng)的結(jié)構(gòu)辦法在內(nèi)存中對應(yīng)的是Constructor目標(biāo),特點(diǎn)對應(yīng)的便是Field,而辦法呢對應(yīng)的便是Method,可是不論咱們想要取得結(jié)構(gòu)辦法,特點(diǎn)仍是辦法,前提都是咱們先取得Class目標(biāo).
二.Class類
Java中java.lang.Class類用于表明一個類的字節(jié)碼(.class)文件
如何得到某個class文件對應(yīng)的Class目標(biāo)
已知類和目標(biāo)的情況下
類名.class
目標(biāo).getClass()—Object類供給
未知類和目標(biāo)的情況下
Class.forName(“包名.類名”)
Class類代表某個類的字節(jié)碼,并供給了加載字節(jié)碼的辦法:forName(“包名.類名”),forName辦法用于加載類字節(jié)碼到內(nèi)存中,并封裝成一個Class目標(biāo).
packageJavaReflectTest;publicclassAnimal{publicStringname;privateintid;publicAnimal(){System.out.println(“我是無參結(jié)構(gòu)辦法”);}publicAnimal(intid,Stringname){this.setId(id);this.setName(name);System.out.println(“我是有參結(jié)構(gòu)辦法”);}publicvoideat(){System.out.println(“我是公有辦法”);}privatevoiddrink(){System.out.println(“我是私有辦法”);}privatevoidplay(Stringname,Stringsex){System.out.println(“我是私有帶參辦法”);}@OverridepublicStringtoString(){return”Animal{“+”name='”+name+’\”+”,id=”+id+’}’;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}}
packageJavaReflectTest;publicclassClassTest{/**
*取得Class目標(biāo)
*1.經(jīng)過類名.class
*2.目標(biāo).getClass()
*3.Class.forName();
*/publicvoiddemo1()throwsClassNotFoundException{//1.經(jīng)過類名.class的辦法Classclass1=Animal.class;//2.經(jīng)過目標(biāo).getClass()的辦法Animalanimal=newAnimal();Classclass2=animal.getClass();//3.Class類forName();取得(推薦)Classclass3=Class.forName(“JavaReflectTest.Animal”);}publicstaticvoidmain(String[]args){}}
這三種取得Class目標(biāo)的辦法,推薦運(yùn)用第三種辦法,因?yàn)樵蹅兺ǔW龇瓷涞臅r分,都是在不知道類的實(shí)例的時分進(jìn)行操作的,注意第三種辦法經(jīng)過Class.forName();來取得Class目標(biāo)的時分,會拋出一個ClassNotFoundException沒有發(fā)現(xiàn)類的反常,假如咱們Class.forName(“途徑”);途徑寫錯了或許沒有找到這個類的時分,就會拋出這個反常,當(dāng)然這個反常處理,你能夠挑選try…catch處理也能夠先向上拋,我這兒為了便利,就直接向上拋了
三.Constructor類
Constructor類的實(shí)例目標(biāo)代表類的一個結(jié)構(gòu)辦法
得到某個類一切的結(jié)構(gòu)辦法
Constructor[]constructors=Class.forName(“java.lang.String”).getConstructors();
得到指定的結(jié)構(gòu)辦法并調(diào)用
Constructorconstructor=Class.forName(“java.lang.String”).getConstructors(String.class);
Stringstr=(String)constructor.newInstance(“abc”);
Class類的newInstance()辦法用來調(diào)用類的默認(rèn)結(jié)構(gòu)辦法
Stringobj=(String)Class.forName(“java.lang.String”).newInstance();
packageJavaReflectTest;importjava.lang.reflect.Constructor;publicclassConstructorTest{/**
*取得無參結(jié)構(gòu)辦法
*/publicvoiddemo1()throwsException{//取得類的字節(jié)碼文件對應(yīng)的目標(biāo):Classclass1=Class.forName(“JavaReflectTest.Animal”);Constructorc=class1.getConstructor();Animalanimal=(Animal)c.newInstance();//相當(dāng)于Animalanimal=newAnimal();}/**
*取得有參結(jié)構(gòu)辦法
*/publicvoiddemo2()throwsException{Classclass1=Class.forName(“JavaReflectTest.Animal”);Constructorc=class1.getConstructor(int.class,String.class);Animalanimal=(Animal)c.newInstance(2,”山公”);//相當(dāng)于Animalanimal=newAnimal(2,”山公”);System.out.println(animal.toString());}publicstaticvoidmain(String[]args)throwsException{ConstructorTestc=newConstructorTest();c.demo1();System.out.println(“————“);c.demo2();}}
運(yùn)轉(zhuǎn)成果
在這兒刺進(jìn)圖片描繪
四.Field類
Field類代表某個類中的一個成員變量,并供給動態(tài)的拜訪權(quán)限
Field目標(biāo)的取得
Field[]fields=c.getFields();//取得一切public特點(diǎn)(包含父類承繼)
Field[]fields=c.getDeclaredFields();//取得一切聲明的特點(diǎn)
得到指定的成員變量
Fieldname=c.getField(“name”);
Fieldname=c.getDeclaredField(“name”);
設(shè)置Filed變量是否能夠拜訪
field.setAccessible(boolean);
-Field變量值的讀取,設(shè)置
field.get(obj);
filed.set(obj,value);
packageJavaReflectTest;importjava.lang.reflect.Field;publicclassFieldTest{//測驗(yàn)共有特點(diǎn)publicvoiddemo1()throwsException{//取得ClassClassclass1=Class.forName(“JavaReflectTest.Animal”);//取得特點(diǎn):Fieldfield=class1.getField(“name”);//操作特點(diǎn):Animalanimal=(Animal)class1.getConstructor().newInstance();field.set(animal,”老虎”);//animal.name=”老虎”;//獲取值Objectobj=field.get(animal);System.out.println(obj);System.out.println(animal);//這樣會主動調(diào)用toString()辦法}//測驗(yàn)私有辦法publicvoiddemo2()throwsException{//取得ClassClassclass1=Class.forName(“JavaReflectTest.Animal”);//取得私有特點(diǎn):Fieldfield=class1.getDeclaredField(“id”);//操作特點(diǎn):Animalanimal=(Animal)class1.getConstructor().newInstance();//私有特點(diǎn),需求設(shè)置一個可拜訪的權(quán)限field.setAccessible(true);field.set(animal,1);//獲取值:Objectobj=field.get(animal);System.out.println(obj);System.out.println(animal);}publicstaticvoidmain(String[]args)throwsException{FieldTestfieldTest=newFieldTest();fieldTest.demo1();System.out.println(“—————-“);fieldTest.demo2();}}
效果圖
在這兒刺進(jìn)圖片描繪
五.Method類
Method類代表某個類中的一個成員辦法
Method目標(biāo)的取得
取得一切辦法
getDeclaredMethods()
getMethods()
-取得指定的辦法
getDeclaredMethod(Stringname,Class…parameterTypes)
getMethod(Stringname,Class…parameterTypes)
經(jīng)過反射履行辦法
invoke(Objectobj,Object…args)
packageJavaReflectTest;importjava.lang.reflect.Method;publicclassMethodTest{//測驗(yàn)公有辦法publicvoiddemo1()throwsException{//獲取Class目標(biāo)Classclass1=Class.forName(“JavaReflectTest.Animal”);//實(shí)例化Animalanimal=(Animal)class1.getConstructor().newInstance();//取得公有辦法Methodmethod=class1.getMethod(“eat”);//履行該辦法method.invoke(animal);//相當(dāng)于animal.eat();}//測驗(yàn)私有辦法publicvoiddemo2()throwsException{//獲取Class目標(biāo)Classclass1=Class.forName(“JavaReflectTest.Animal”);//實(shí)例化Animalanimal=(Animal)class1.getConstructor().newInstance();//取得私有辦法Methodmethod=class1.getDeclaredMethod(“drink”);//設(shè)置私有的拜訪權(quán)限method.setAccessible(true);//履行該辦法method.invoke(animal);//相當(dāng)于animal.drink();}publicvoiddemo3()throwsException{//獲取Class目標(biāo)Classclass1=Class.forName(“JavaReflectTest.Animal”);//實(shí)例化Animalanimal=(Animal)class1.getConstructor().newInstance();//取得私有帶參的辦法Methodmethod=class1.getDeclaredMethod(“play”,int.class,String.class);//設(shè)置私有的拜訪權(quán)限method.setAccessible(true);//履行該辦法Objectobj=method.invoke(animal,2,”孔雀”);//這是有返回值的情況假如沒有返回值能夠直接寫method.invoke(animal,2,”孔雀”);System.out.println(obj);//打印返回的東西,沒有便是null}//測驗(yàn)私有帶參數(shù)的辦法publicstaticvoidmain(String[]args)throwsException{MethodTestmethodTest=newMethodTest();methodTest.demo1();System.out.println(“——————–“);methodTest.demo2();System.out.println(“——————–“);methodTest.demo3();}}
廣州天河區(qū)珠江新城富力盈力大廈北塔2706
020-38013166(網(wǎng)站咨詢專線)
400-001-5281 (售后服務(wù)熱線)
深圳市坂田十二橡樹莊園F1-7棟
Site/ http://www.szciya.com
E-mail/ itciya@vip.163.com
品牌服務(wù)專線:400-001-5281
長沙市天心區(qū)芙蓉中路三段398號新時空大廈5樓
聯(lián)系電話/ (+86 0731)88282200
品牌服務(wù)專線/ 400-966-8830
旗下運(yùn)營網(wǎng)站:
Copyright ? 2016 廣州思洋文化傳播有限公司,保留所有權(quán)利。 粵ICP備09033321號