反射——反射API,使用反射創建數組


反射API

Java.lang.Reflect庫

①   Class類與Java.lang.Reflect類庫一起對反射的概念進行支持。

②   java.lang包下:

a)         Class<T>:表示對一個正在運行的Java應用程序中的類和接口,是Reflection的起源。

③   java.lang.reflect包下:

a)         Field類:代表類的成員變量(成員變量也稱類的屬性)。

b)         Method類:代表類的方法。

c)         Constructor類:代表類的構造方法。

d)         Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法。

 

 

通過反射實例化對象

① 常情況下我們通過new Object來生成一個類的實例,但有時我們沒法直接new,只能通過反射動態生成。

② 實例化無參構造函數的對象,兩種方式:

a)         Class.newlnstance();

b)         Class.getConstructor(new Class[]{}).newInstance(new Object[]{})

③ 實化帶參構造函數的對象

a)         clazz.getConstructor(Class<?>… parameterTypes).newInstance(Object… initargs)

 

通過反射獲取並調用方法

① 得當前類以及超類的public Method(共有方法)

a)         Method[] arrMethod=classType.getMethods();

② 得當前類申明的所有Method

a)         Method[] arrMethod=classType.getDeclaredMethods();

③ 獲得當前類以及超類指定的public Method

a)         Method method=classType.getMethod(String name,Class<?>… parameterTypes);

④ 得當前類申明的指定的Method

a)         Method method=classType. getDeclaredMethods (String name,Class<?>… parameterTypes);

⑤ 通過反射動態運行指定Method

a)         Object obj=method.invoke(Object obj,Object… args);

 

通過反射獲取並調用屬性

① 得當前類以及超類的public Field

a)Field[] arrFields=classType.getField();

② 獲得當前類申明的所有Field

a)Field[] arrFields=classType.getDeclaredFields();

③ 獲得當前類以及超類指定的public Field

a)       Field field=classType.getField(String name);

④ 獲得當前類申明的指定的Field

a)         Field field=classType.getDeclaredField(String name);

⑤ 通過反射動態設定Field的值

a)         field.set(Object obj,Object value);

⑥ 通過反射動態獲取Field的值

a)         Object obj=field.get(Object obj);

 

----------------------------------------------------------------------------------------------------

代碼

創建一個Employee類

 1 class Employee {  2     private String name;  3     private int age;  4 
 5     public Employee() {  6         System.out.println("無參構造方法");  7  }  8 
 9     public String getName() { 10         return name; 11  } 12 
13     public void setName(String name) { 14         this.name = name; 15  } 16 
17     public int getAge() { 18         return age; 19  } 20 
21     public void setAge(int age) { 22         this.age = age; 23  } 24 
25     public Employee(String name, int age) { 26         super(); 27         this.name = name; 28         this.age = age; 29  } 30 
31  @Override 32     public String toString() { 33         return "Employee [name=" + name + ", age=" + age + "]"; 34  } 35 
36     private void work() { 37         System.out.println("working..."); 38  } 39 
40 }

 

在主方法中獲取類的屬性及方法:

1         // 獲取Employee這個類所關聯的class對象
2         Class<?> classType = Class.forName("com.iotek.reflection.Employee"); 3         // 通過反射機制來構造一個Employee的實例對象(默認調用無參數的構造方法)
4         Employee employee = (Employee) classType.newInstance(); 5         System.out.println(employee);

輸出結果:

無參構造方法

Employee [name=null, age=0]

 

1         // 調用指定的構造方法來構造對象(無參構造方法)
2         Constructor<?> constructor = classType.getConstructor(new Class[] {}); 3         Employee employee2 = (Employee)constructor.newInstance(new Object[] {}); 4         System.out.println(employee2);

輸出結果:

無參構造方法

Employee [name=null, age=0]

 

1         // 調用指定的構造方法來構造對象(帶參構造方法)
2         Constructor<?> constructor2 = classType.getConstructor(new Class[] {String.class, int.class }); 3         Employee employee3 = (Employee) constructor2.newInstance(new Object[] {"zhangsan", 20 }); 4         System.out.println(employee3);

輸出結果:

Employee [name=zhangsan, age=20]

 

1         // 獲取Class對象所指定的所有方法,包括私有的
2         Method[] methods = classType.getDeclaredMethods(); 3         for (Method method : methods) { 4             System.out.println(method.getName() + "--" + method.getModifiers() 5                     + "--" + method.getReturnType()); 6         }

輸出結果:

toString--1--class java.lang.String

getName--1--class java.lang.String

setName--1--void

work--2--void

getAge--1--int

setAge--1—void

 

1         // 獲取Class對象所指定的方法,包括私有的
2         Method method2 = classType 3                 .getDeclaredMethod("toString", new Class[] {}); 4  System.out.println(method2); 5         // 方法的調用
6         String desc = (String) method2.invoke(employee3, new Object[] {}); 7         System.out.println(desc);

輸出結果:

public java.lang.String com.iotek.reflection.Employee.toString()

Employee [name=zhangsan, age=20]

 

1         // 調用私有方法
2         Method method3 = classType.getDeclaredMethod("work", new Class[] {}); 3  System.out.println(method3.getName()); 4         method3.setAccessible(true);// 設置私有方法可以訪問 5         // 方法的調用
6         method3.invoke(employee3, new Object[] {});

輸出結果:

work

working...

 

1         // 獲取Class對象所指定的屬性,包括私有的
2         Field field = classType.getDeclaredField("name"); 3         field.setAccessible(true); 4         field.set(employee3, "李四"); 5         System.out.println(field.get(employee3));

輸出結果:

李四

 

使用反射來創建一維數組:

1         // 創建一個一維數組(String)
2         Class<?> classType = Class.forName("java.lang.String"); 3         Object array = Array.newInstance(classType, 5); 4         Array.set(array, 3, "abc"); 5         System.out.println(Array.get(array, 3));

輸出結果:

abc

 

使用反射來創建二維數組:

1         // 創建一個二維數組(3行3列)
2         int[] dimens = { 3, 3 }; 3         Object array2 = Array.newInstance(int.class, dimens); 4         Object arrayObj = Array.get(array2, 2);// 獲取第三行(就是一個一維數組)
5         Array.setInt(arrayObj, 2, 10);// 給指定數組位置的元素賦值
6         int [][] arr = (int [][]) array2; 7         System.out.println(arr[2][2]);

輸出結果:

10

 

反射總結

①   只要用到反射,先獲得Class對象。

②   沒有方法能獲得當前類的超類的private方法和屬性,你必須通過getSuperclass()找到超類以后再去嘗試獲得。

③   通常情況下即使是當前類,private屬性或方法也是不能訪問的,你需要設置壓制權限setAccessible(true)來取得private的訪問權。但是,這已經破壞了面向對象的規則,所以除非萬不得已,請盡量少用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM