反射的作用
在不修改原始碼的情況下,擴充套件功能。
程式在執行的時期,透過反射機制,獲取類的所有內部資訊,並且操作類的物件。
Class類
- 一個類在堆中只有一個Class物件,這個Class物件包含了類的完整結構資訊
- 反射技術是針對Class物件進行操作,在程式執行的時候,動態獲取類中的所有成員
[1] Class類 常用方法
透過類的全路徑名 獲取Class物件
獲取類載入器
獲取例項物件
獲取構造器物件
獲取成員屬性物件
獲取成員方法物件
[2] 獲取Class類物件
獲取Class類物件的4種方式
基本型別和包裝型別的Class物件
- int.class
- char.class
- Integer.TYPE
- Charater.TYPE
其它型別的Class物件
Constructor類
建立例項物件
//獲取Class類物件
Class<?> clazz = Class.forName(className);
//獲取空參構造器物件
Constructor<?> constructor = clazz.getConstructor();
Student stu= (Student)constructor.newInstance();
//獲取有參構造器物件
Constructor<?> constructor = clazz.getConstructor(String.class,int.class);
Student stu= (Student)constructor.newInstance("www", 50);
Field類
- 設定值:set( 例項物件, 值 )
- 獲取值:get( 例項物件 )
- 靜態屬性:set( null, 值 ) / get( null )
Method類
使用反射的步驟
應用例項
[1] 使用反射 - 建立物件
//1.獲取User類的Class物件
Class<?> cls = Class.forName("com.java.test.Student");
//2.無參構造器建立物件
Object o = cls.newInstance();
//3.有參構造器建立物件
Constructor<?> constructor = cls.getConstructor(int.class, String.class);
Object o2 = constructor.newInstance(1000, "hello");
//4.私有有參構造器建立物件
Constructor<?> declaredConstructor = cls.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
Object o3 = declaredConstructor.newInstance("jack");
[2] 使用反射 - 操作屬性
//獲取Class物件
Class<PrivateTest> cls = PrivateTest.class;
//使用Class類物件,建立例項物件
PrivateTest o = cls.newInstance();
//獲取指定的欄位物件
Field nameFieldObj = cls.getDeclaredField("name");
nameFieldObj.setAccessible(true);
nameFieldObj.set(o,"汪汪");
//獲取指定的方法物件
Method getNameObj = cls.getMethod("getName");
System.out.println(getNameObj.invoke(o));
[3] 使用反射 - 呼叫方法
- 獲取Class類物件
- 獲取所有的成員方法物件:getDeclaredMethods( )
- 取消訪問檢查:setAccessible(true);
- 呼叫方法:invoke( )
[4] 透過配置檔案,建立物件並呼叫方法
配置檔案
classfullpath=com.reflectiontest.demo.domain.Cat
method=hi
name=zhangsan
age=19
main方法
//1. 透過類載入器讀取src目錄下的配置檔案
// 獲取類載入器
ClassLoader clazzLoader = DemoTest02.class.getClassLoader();
// 讀取配置檔案
InputStream is = clazzLoader.getResourceAsStream("stu.ini");
Properties pro = new Properties();
pro.load(is);
String classfullpath = pro.getProperty("classfullpath");
String method = pro.getProperty("method");
String name = pro.getProperty("name");
int age = Integer.parseInt(pro.getProperty("age"));
//2.使用反射技術
//根據全類名獲取Class物件
Class<?> cls = Class.forName(classfullpath);
//透過Class類 獲取物件例項
Object o = cls.newInstance();
//獲取空參構造器物件
Constructor<?> constructor = clazz.getConstructor();
Student stu= (Student)constructor.newInstance();
//獲取有參構造器物件
Constructor<?> constructor = clazz.getConstructor(String.class,int.class);
Student stu= (Student)constructor.newInstance("www", 50);
//操作屬性
System.out.println("--透過Field物件獲取私有屬性的值--");
Field nameObj = cls.getDeclaredField("name");
nameObj.setAccessible(true);
System.out.println(nameObj.get(o));//獲取屬性的值
nameObj.set(o,"newName");//設定屬性的值
//操作方法
//獲取Method物件
Method methodObj1 = cls.getMethod(method);
//透過Method物件呼叫方法
methodObj1.invoke(o);