反射机制-Reflected
一、java的反射機(jī)制提供的功能:
- 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類
- 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象
- 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法
- 運(yùn)行時(shí)獲取泛型信息
- 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的成員變量和方法
- 在運(yùn)行時(shí)處理注解
- 生成動(dòng)態(tài)代理
二、反射相關(guān)的主要API:
-
java.lang.Class : 代表一個(gè)類
1.程序經(jīng)過javac.exe命令以后,會(huì)生成一個(gè)或多個(gè)字節(jié)碼文件(.calss后綴)。
接著我們使用就java.exe命令對(duì)猴哥字節(jié)碼文件進(jìn)行解釋運(yùn)行,此過程相當(dāng)于將某個(gè)字節(jié)碼文件加載帶內(nèi)存中。上述過程稱之為累的加載。
加載到內(nèi)存中的類為運(yùn)行時(shí)的類,運(yùn)行時(shí)的類就作為Class的一個(gè)實(shí)例2.獲取Class的實(shí)例方式
方式1(掌握):Class<> c = 類名.class
方式2(掌握):類名 對(duì)象名 = new 類名()
Class c = 對(duì)象名.getClass()
方式3(掌握):Class c = Class.forName(String classPath)(注意:會(huì)拋異常)3.那些類型可以有Class對(duì)象
1.class :外部類、成員內(nèi)部類、靜態(tài)內(nèi)部類、局部?jī)?nèi)部類、匿名類
2.interface : 接口
3.[] : 數(shù)組
4.enum : 枚舉
5.annotation : 注解@interface
6.primitive type : 基本數(shù)據(jù)類型
7.void -
java.lang.reflect.Constructor : 代表類的構(gòu)造器
1.獲取當(dāng)前類的public構(gòu)造器
Constructor[] 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getConstructors()2.獲取當(dāng)前類的所有的構(gòu)造器
Constructor[] 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getDecleardConstructors()3.獲取指定的構(gòu)造器
Constructor 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getConstructor(參數(shù)1類型.class,…) -
創(chuàng)建運(yùn)行時(shí)類的實(shí)例對(duì)象
方式1:使用的是類中的指定的構(gòu)造器創(chuàng)建的類對(duì)象【不常用】
Constructor 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getConstructor(參數(shù)1類型.class,…) 獲取指定構(gòu)造器對(duì)象
構(gòu)造器對(duì)象名.setAccessible(true) 表示允許操作private成員
Object obj = 構(gòu)造器對(duì)象名.newInstance(參數(shù)1,…) 通過指定構(gòu)造器對(duì)象創(chuàng)建類的對(duì)象方式2:這樣直接使用的是類中的空參構(gòu)造器創(chuàng)建的類對(duì)象【常用】
Object obj = Class的實(shí)例名.newInstance() -
java.lang.reflect.Field : 代表類的成員變量
1.獲取到類中public屬性(包含父類)【不建議使用
方法1:
Field[] f = Class的實(shí)例名.getFields()
方法2:
Field f = Class的實(shí)例名.getField(屬性名)2.獲取到類中自己的所有屬性(不含有父類):【建議使用】
方法1:
Field[] f = Class的實(shí)例名.getDeclaredFields()
方法2:
Field f = Class的實(shí)例名.getDeclaredField(屬性名)3.獲取到屬性的權(quán)限修飾符、數(shù)據(jù)類型、變量名。(了解)
int f.getModifiers() : 權(quán)限修飾符(0代表默認(rèn),1代表public,2代表private)Class f.getType().getName() : 數(shù)據(jù)類型
String f.getName() : 變量名
4.設(shè)置、獲取 屬性的值
非靜態(tài)的屬性:
前提操作:f.setAccessible(true) 表示允許操作private成員
設(shè)置:f.set(obj,value) obj表示給哪個(gè)對(duì)象的屬性設(shè)置,value為設(shè)置的值
獲取:f.get(obj) obj表示獲取哪個(gè)對(duì)象的屬性值,有返回值靜態(tài)的屬性:
前提操作:f.setAccessible(true) 表示允許操作private成員
設(shè)置:f.set(類.class,value) 類.class:表示當(dāng)前類的靜態(tài),value為設(shè)置的值
獲取:f.get(類.class) 類.class:表示當(dāng)前類的靜態(tài),有返回值 -
java.lang.reflect.Method : 代表類的方法
1.獲取到類中public方法(包含父類)【不推薦使用】
方法1:
Method[] m = Class的實(shí)例名.getMethods()方法2:
Method m = Class的實(shí)例名.getMethod(方法名,形參列表(默認(rèn)為空))2.獲取到類中自己的所有方法(不含有父類)【推薦使用】
方法1:
Method[] m = Class的實(shí)例名.getDeclaredMethods()
方法2:
Method m = Class的實(shí)例名.getDeclaredMethod(方法名,形參列表(默認(rèn)為空)) 例:String型的形參列表:String.class3.調(diào)用方法
非靜態(tài)方法:
前提操作:m.setAccessible(true) 表示允許操作private成員
調(diào)用:m.invoke(obj,實(shí)參1,…) obj表示給哪個(gè)對(duì)象的屬性設(shè)置,實(shí)參對(duì)應(yīng)的方法的形參。invoke()返回值就是類中方法的返回值靜態(tài)方法:
前提操作:m.setAccessible(true) 表示允許操作private成員
調(diào)用:m.invoke(類.class,實(shí)參1,…) 類.class:表示當(dāng)前類的靜態(tài),實(shí)參對(duì)應(yīng)的方法的形參。invoke()返回值就是類中方法的返回值 -
…
三、方法的補(bǔ)充:
1.獲取運(yùn)行時(shí)類的父類
Class sp = Class的實(shí)例名.getSuperclass()
2.獲取運(yùn)行時(shí)類的帶泛型的父類
Type sgp = Class的實(shí)例名.getGenericSuperclass()
3.獲取運(yùn)行時(shí)類的帶泛型的父類的泛型(需要4步)
①Type sgp = Class的實(shí)例名.getGenericSuperclass(). : 獲取運(yùn)行時(shí)類的帶泛型的父類
②ParameterizedType paramType = (parameterizedType)sgp : 強(qiáng)轉(zhuǎn)
③Type[] actTypeArg = paramType.getActualTypeArguments() : 獲取到實(shí)際的類型參數(shù)(也就是泛型)
④actTypeArg.getTypeName() : 獲取泛型名
4.獲取到當(dāng)前運(yùn)行時(shí)類的接口
Class[] interface = Class的實(shí)例名.getInterface()
如果想獲取到其父類的接口,那么得到父類然后在getInterface()
5.獲取當(dāng)前運(yùn)行時(shí)類所在的包
Package pk = Class的實(shí)例名.getPackage()
6.獲取當(dāng)前運(yùn)行時(shí)類聲明的注解
Annotation[] anno = Class的實(shí)例名.getAnnotations()
四、使用反射之前能對(duì)Person的操作:
- 創(chuàng)建Person類的實(shí)例化
- 通過對(duì)象當(dāng)調(diào)用類中的非private類型的屬性、方法
五、使用反射之后能對(duì)Person的操作
- 創(chuàng)建Person類的實(shí)例化(調(diào)用構(gòu)造器)
- 調(diào)用Person中的屬性
- 調(diào)用Person中的方法
- 調(diào)用Person中private的屬性、方法、構(gòu)造器
上述過程的相關(guān)代碼舉例:
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class ReflectionTest {public static void main(String[] args) throws Exception {Person p1 = new Person("Joney",18);System.out.println(p1.age);System.out.println(p1.toString()+"\n");System.out.println("**************************");//1.通過反射創(chuàng)建Person的對(duì)象objClass c = Person.class;Object newInstance = c.newInstance();System.out.println(newInstance.toString());//通過getConstructor(參數(shù)1類型.class,...)獲取構(gòu)造器對(duì)象Constructor constructor = c.getConstructor(String.class,int.class);//獲取構(gòu)造器對(duì)象Object obj = constructor.newInstance("Mike",22);//通過構(gòu)造器對(duì)象實(shí)例化Person//通過對(duì)象調(diào)用Person的方法System.out.println(obj.toString()+"\n"); //通過反射創(chuàng)建Person的對(duì)象obj調(diào)用方法//2.調(diào)屬性Field age = c.getDeclaredField("age"); //通過getDeclaredField("屬性")獲取到該屬性的對(duì)象age.set(obj, 20); //修改屬性值System.out.println(obj.toString()+"\n");//3.調(diào)方法Method print = c.getDeclaredMethod("print");//通過getDeclaredMethod()獲取到該方法的對(duì)象print.invoke(obj); //調(diào)用該print()System.out.println();//4.調(diào)用private結(jié)構(gòu)//4.1通過getDeclaredConstructor((參數(shù)1類型.class,...)獲取私有構(gòu)造器對(duì)象Constructor privateConstructor = c.getDeclaredConstructor(String.class);//獲取私有構(gòu)造器對(duì)象privateConstructor.setAccessible(true);Object obj2 = privateConstructor.newInstance("Tom");//創(chuàng)建對(duì)象System.out.println(obj2.toString());//4.2通過getDeclaredField("屬性名")獲取到私有屬性的對(duì)象Field name = c.getDeclaredField("name");name.setAccessible(true);name.set(obj2, "Aimy");//修改屬性值System.out.println(obj2.toString());} } class Person{private String name;public int age;public Person(String name, int age) {super();this.name = name;this.age = age;}private Person(String name) {super();this.name = name;}public Person() {super();}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void print() {System.out.println("我是Person的print()");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}}總結(jié)
以上是生活随笔為你收集整理的反射机制-Reflected的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#制作软键盘
- 下一篇: 美团和大众点评早期分别以交易和用户评价进