java反射
反射:動(dòng)態(tài)獲取類的信息蘸鲸,以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能噪伊≌テ牛可以理解為動(dòng)態(tài)看透類的能力磁携。
主要功能:
- 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類;
- 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象良风;
- 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法谊迄;
- 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法,生成動(dòng)態(tài)代理拖吼。
通過(guò)java反射機(jī)制鳞上,可以在程序中訪問(wèn)已經(jīng)裝載到JVM中的java對(duì)象的描述,實(shí)現(xiàn)訪問(wèn)吊档、檢測(cè)和修改描述java對(duì)象本身信息的功能篙议。java反射機(jī)制的功能十分強(qiáng)大,java.lang.reflect包中提供了對(duì)該功能的支持怠硼。
通過(guò)反射獲取類的三種方法
//1鬼贱、第一種方式-->Class.forName("類名字符串");
//注:類名字符串是"包名+類名" 返回Class的對(duì)象。(這種是最常用的方法)
Class c1 = Class.forName("csdn.Student");
//2香璃、第二種方式-->先創(chuàng)建對(duì)象,再用對(duì)象調(diào)用getClass()方法这难,返回運(yùn)行時(shí)類。
Student s = new Student();
Class c2 = s.getClass();
//3葡秒、第三種方式-->類名.class姻乓。返回Class的對(duì)象。(每個(gè)類都有class屬性)
Class c3 = Student.class;
獲取描述信息
- 獲取構(gòu)造方法
方法 | 返回值 | 功能描述 |
---|---|---|
getConstructors() | Constructor型數(shù)組 | 獲取所有"公有的"構(gòu)造方法 |
getDeclaredConstructors() | Constructor型數(shù)組 | 獲取所有的構(gòu)造方法(包括私有眯牧、受保護(hù)蹋岩、默認(rèn)、公有) |
getConstructor(Class<?>... paramsTypes) | Constructor對(duì)象 | 獲取單個(gè)的"公有的"構(gòu)造方法 |
getDeclaredConstructor(Class<?>... paramsTypes) | Constructor對(duì)象 | 獲取"某個(gè)構(gòu)造方法"可以是私有的学少,或受保護(hù)剪个、默認(rèn)、公有 |
//1.加載Class對(duì)象
Class clazz = Class.forName("fanshe.Student");
//2.獲取所有公有構(gòu)造方法
Constructor[] conArray = clazz.getConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
//3.獲取所有的構(gòu)造方法(包括:私有版确、受保護(hù)扣囊、默認(rèn)、公有)
conArray = clazz.getDeclaredConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
//4.獲取公有绒疗、無(wú)參的構(gòu)造方法
Constructor con = clazz.getConstructor(null);
//1侵歇、因?yàn)槭菬o(wú)參的構(gòu)造方法所以類型是一個(gè)null,不寫(xiě)也可以,這里需要的是一個(gè)參數(shù)的類型吓蘑,切記是類型
//2盒至、返回的是描述這個(gè)無(wú)參構(gòu)造函數(shù)的類對(duì)象。
//調(diào)用構(gòu)造方法
Object obj = con.newInstance();
Student stu = (Student)obj;
//5.獲取私有構(gòu)造方法,并調(diào)用
con = clazz.getDeclaredConstructor(char.class);
//調(diào)用構(gòu)造方法
con.setAccessible(true);//暴力訪問(wèn)(忽略掉訪問(wèn)修飾符)
obj = con.newInstance('男');
- 獲取屬性
方法 | 返回值 | 功能描述 |
---|---|---|
getFields() | Field型數(shù)組 | 獲取所有的"公有字段" |
getDeclaredFields() | Field型數(shù)組 | 獲取所有字段枷遂,包括:私有、受保護(hù)棋嘲、默認(rèn)酒唉、公有,但不包括繼承來(lái)的 |
getField(String name) | Field對(duì)象 | 獲取某個(gè)"公有的"字段 |
getDeclaredField(String name) | Field對(duì)象 | 獲取某個(gè)字段(可以是私有的) |
//1.獲取Class對(duì)象
Class stuClass = Class.forName("fanshe.field.Student");
//2.獲取所有公有的字段
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
//3.獲取所有的字段(包括私有沸移、受保護(hù)痪伦、默認(rèn)的)
fieldArray = stuClass.getDeclaredFields();
for(Field f : fieldArray){
System.out.println(f);
}
//4.獲取指定公有字段并調(diào)用
Field f = stuClass.getField("name");
//獲取一個(gè)對(duì)象
Object obj = stuClass.getConstructor().newInstance();//Student stu = new Student();
//為字段設(shè)置值
f.set(obj, "劉德華");//stu.name = "劉德華"
//驗(yàn)證
Student stu = (Student)obj;
System.out.println("驗(yàn)證姓名:" + stu.name);
//5.獲取指定私有字段并調(diào)用
f = stuClass.getDeclaredField("phoneNum");
f.setAccessible(true);//暴力反射,解除私有限定
f.set(obj, "18888889999");
System.out.println("驗(yàn)證電話:" + stu);
- 獲取方法
方法 | 返回值 | 功能描述 |
---|---|---|
getMethods() | Method型數(shù)組 | 獲取所有"公有方法"(包含了父類的方法也包含Object類) |
getDeclaredMethods() | Method型數(shù)組 | 獲取所有的成員方法雹锣,包括私有的(不包括繼承的) |
getMethod(String name, Class<?>.. paramsTypes) | Method對(duì)象 | 獲取指定的"公有方法" |
getDeclaredMethod(String name, Class<?>.. paramsTypes) | Method對(duì)象 | 獲取指定的方法(包括私有的) |
//1.獲取Class對(duì)象
Class stuClass = Class.forName("fanshe.method.Student");
//2.獲取所有公有方法
Method[] methodArray = stuClass.getMethods();
for(Method m : methodArray){
System.out.println(m);
}
//獲取所有的方法网沾,包括私有的
methodArray = stuClass.getDeclaredMethods();
for(Method m : methodArray){
System.out.println(m);
}
//獲取公有的show1()方法
Method m = stuClass.getMethod("show1", String.class);
//實(shí)例化一個(gè)Student對(duì)象
Object obj = stuClass.getConstructor().newInstance();
m.invoke(obj, "劉德華");
//獲取私有的show4()方法
m = stuClass.getDeclaredMethod("show4", int.class);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj,20);
System.out.println("返回值:" + result);