java反射技術詳解


反射

其實就是動態的從內存加載一個指定的類,並獲取該類中的所有的內容。

反射的好處:大大的增強了程序的擴展性。

 

反射的基本步驟:
  1. 獲得Class對象,就是獲取到指定的名稱的字節碼文件對象。
  2. 實例化對象,獲得類的屬性、方法或構造函數。
  3. 訪問屬性、調用方法、調用構造函數創建對象。

一: 獲取Class對象,有三種方式 :
  1:通過每個對象都具備的方法getClass來獲取。弊端:必須要創建該類對象,才可以調用getClass方法。
  2:每一個數據類型(基本數據類型和引用數據類型)都有一個靜態的屬性class。弊端:必須要先明確該類。
  前兩種方式不利於程序的擴展,因為都需要在程序使用具體的類來完成。
  3:使用的Class類中的方法,靜態的forName方法。指定什么類名,就獲取什么類字節碼文件對象,這種方式的擴展性最強,只要將類名的字符串傳入即可。

   1 Class clazz = Class.forName("com.makaruina.reflect.Person"); 

二: 獲取了字節碼文件對象后,然后就需要創建指定類的對象:

  創建對象的兩種方式(其實就是對象在進行實例化時的初始化方式):

  1. 調用空參數的構造函數:

    使用了Class類中的newInstance()方法。

  2. 調用帶參數的構造函數:

    先要獲取指定參數的構造器對象,然后通過該構造器對象的newInstance(實際參數) 進行對象的初始化。

1 Class clazz = Class.forName("com.makaruina.reflect.Person");
2 Constructor con = clazz.getConstructor(new Class[]{String.class,int.class});
3 Person instance = (Person) con.newInstance("name",20);

綜上所述,第二種方式,必須要先明確具體的構造函數的參數類型,不便於擴展。所以一般情況下,被反射的類,內部通常都會提供一個公有的空參數的構造函數。

三:獲取類中的方法,屬性,構造函數。

  1. 獲取方法

 1 //獲取類中所有的方法。
 2         public static void method_1() throws Exception {
 3             Class clazz = Class.forName("com.makaruina.reflect.Person");
 4             //獲取的是該類中所有的公有方法,包含繼承和實現的方法。
 5             Method[] methods = clazz.getMethods();
 6             //獲取的是該類中的所有方法,包含私有方法,但不包含繼承的方法。
 7             methods = clazz.getDeclaredMethods();
 8             for(Method method : methods) {
 9                 System.out.println(method);
10             }
11         }
12         //獲取指定方法;
13         public static void method_2() throws Exception {
14             Class clazz = Class.forName("com.makaruina.reflect.Person");
15             //獲取指定名稱的方法。
16             Method method = clazz.getMethod("show", int.class,String.class);
17             //想要運行指定方法,當然是方法對象最清楚,為了讓方法運行,調用方法對象的invoke方法即可,但是方法運行必須要明確所屬的對象和具體的實際參數。
18             Object obj = clazz.newInstance();
19             method.invoke(obj, 39,"hehehe");//執行一個方法
20         }
21         //想要運行私有方法。
22         public static void method_3() throws Exception {
23             Class clazz = Class.forName("com.makaruina.reflect.Person");
24             //想要獲取私有方法。必須用getDeclearMethod();
25             Method method = clazz.getDeclaredMethod("method", null);
26             // 私有方法不能直接訪問,因為權限不夠。非要訪問,可以通過暴力的方式。
27             method.setAccessible(true);//一般很少用,因為私有就是隱藏起來,所以盡量不要訪問。
28         }
29         //反射靜態方法。
30         public static void method_4() throws Exception {
31             Class clazz = Class.forName("com.makaruina.reflect.Person");
32             Method method = clazz.getMethod("function",null);
33             method.invoke(null,null);
34         }

 

  2.獲取屬性

1 Field getField(String name) 
2     返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共成員字段。 
3  Field[] getFields() 
4     返回一個包含某些 Field 對象的數組,這些對象反映此 Class 對象所表示的類或接口的所有可訪問公共字段。 
5  Field getDeclaredField(String name) 
6     返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。 
7  Field[] getDeclaredFields() 
8     返回 Field 對象的一個數組,這些對象反映此 Class 對象所表示的類或接口所聲明的所有字段。

  3.獲取構造函數

1  Constructor<T> getConstructor(Class<?>... parameterTypes) 
2     返回一個 Constructor 對象,它反映此 Class對象所表示的類的指定公共構造方法。
3  Constructor<?>[] getConstructors() 
4     返回一個包含某些 Constructor 對象的數組,這些對象反映此 Class 對象所表示的類的所有公共構造方法。

好了,反射到這里就說完了,快餓死了。。。。

 

    

 

  

 


免責聲明!

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



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