1. Java反射機制概述
說明
- 反射機制允許程序在執(zhí)行期間借助于反射提供的API獲取任何類的內部信息,并能直接操作任意對象的內部屬性和方法。
- 在加載完類后,在堆內存的方法區(qū)中就產生了一個Class類型的對象(一個類只有一個Class對象),這個對象就包含了完整的類的結構信息,可以通過這個對象看到類的結構
功能
- 在運行時判斷任意一個對象所屬的類
- 在運行時構造任意一個類的對象
- 在運行時判斷任意一個類所具有的成員變量和方法
- 在運行時獲取泛型信息
- 在運行時調用任意一個對象的成員變量和方法
- 在運行時處理注解
- 生成動態(tài)代理
主要的API
- java.lang.Class:代表一個類
- java.lang.reflect.Method:代表類的方法
- java.lang.reflect.Field:代表類的成員變量
- java.lang.reflect.Constructor:代表類的構造器
- ……
2. 理解Class類并獲取Class實例(重點)
反射前后對于一個類操作的比較
public class Reflection01 {
//反射之前,對于Person的操作
@Test
public void test1() {
//1. 創(chuàng)建Perdon類的對象
Person p1 = new Person("費渡", 21);
System.out.println(p1.toString());
//2. 通過對象,調用其內部的屬性、方法
p1.age = 25;
System.out.println(p1.toString());
p1.show();
//此時不可以通過Person類的對象調用其內部私有結構
}
//反射之后,對于Person的操作
@Test
public void test2() throws Exception {
Class personClass = Person.class;
//1.通過反射創(chuàng)建Person類的對象
Constructor constructor = personClass.getConstructor(String.class, int.class);
Person p = (Person) constructor.newInstance("簡隋英", 30);
System.out.println(p.toString());
//2.通過反射,調用對象指定的屬性、方法
//2-1 調用對象的屬性
Field age = personClass.getDeclaredField("age");
age.set(p, 20);
System.out.println(p.toString());
//2-2 調用對象的方法
Method show = personClass.getDeclaredMethod("show");
show.invoke(p);
System.out.println("**************************************");
//3.通過反射,可以調用Person類的私有結構
//3-1 調用私有的構造器
Constructor constructor1 = personClass.getDeclaredConstructor(String.class);
constructor1.setAccessible(true);
Person p1 = (Person) constructor1.newInstance("紀慎語");
System.out.println(p1.toString());
//3-2 調用私有的屬性
Field name = personClass.getDeclaredField("name");
name.setAccessible(true);
name.set(p1, "江停");
System.out.println(p1.toString());
//3-2 調用私有的方法
Method showCouple = personClass.getDeclaredMethod("showCouple", String.class);
showCouple.setAccessible(true);
String couple = (String) showCouple.invoke(p1, "嚴峫");
System.out.println(couple);
}
}
反射與封裝
封裝性的訪問權限控制是一種建議,反射提供了一種調用私有結構的方式
使用哪種方式調用公共結構
建議用直接new的方式
在不確定要new那個類的情況下,使用反射的方式(動態(tài)性)
在JavaWeb書城項目中,解析URL后,通過反射確定要調用的方法
關于java.lang.Class類
- 類的加載過程
程序經(jīng)過javac.exe命令以后,會生成一個或多個字節(jié)碼文件(.class)。
接著使用java.exe命令對某個字節(jié)碼文件進行解釋運行,相當于將某個字節(jié)碼文件加載到內存中,該過程稱為類的加載。加載到內存中的類,被稱為運行時類,該類即作為Class類的一個實例。換句話說,Class的實例就對應著一個運行時類。