反射相關API

读书声起五更天發表於2024-09-20

反射的作用
在不修改原始碼的情況下,擴充套件功能。
程式在執行的時期,透過反射機制,獲取類的所有內部資訊,並且操作類的物件。


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] 使用反射 - 呼叫方法

  1. 獲取Class類物件
  2. 獲取所有的成員方法物件:getDeclaredMethods​( )
  3. 取消訪問檢查:setAccessible(true);
  4. 呼叫方法: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);

相關文章