反射的作用:通過反射獲取屬性和方法


今天主要來談一談反射中獲取成員方法和成員變量的主要方法:

在獲取之前我們首先創造兩個類

Person類(父類):

 1 public class Person {  2     private String name;//私有屬性  3     public Integer age;//公共屬性  4     
 5     public String getName() {  6         return name;  7  }  8     
 9     public void setName(String name) { 10         this.name = name; 11  } 12     
13     public Person() {//空參構造 14         super(); 15  } 16     
17     public void paaa() {//公共方法 18         
19  } 20     
21     private void pbbb() {//私有方法 22         
23  } 24 }

son類(子類):

 1 public class son extends Person{//集成Person類  2     private int age;//私有屬性  3     private String name;  4     public String cname;//公共屬性
 5     public void saaa() {//公共方法  6         
 7  }  8     
 9     private void sbbb() {//私有方法 10         
11  } 12 }

 前言:獲取Class(反射)的三種方式以及獲取對應對象的一個方法:

 

 

我們可以通過上述三種方法獲取相對應的class,如果想要通過class獲取對應的對象,就需要用newInstance方法:

    

1、獲取父類和子類中的內容(公共的):

  1)、獲取父類和子類中的成員變量: 

1 public static void getFields() throws ClassNotFoundException { 2     Class<?> son = Class.forName("com.offcn.wh.reflect.son"); 3     Field[] fields = son.getFields(); 4     for (Field field : fields) { 5  System.out.println(field); 6  } 7 }
  
  結果如下
      
    根據結果可以看出獲取了父類和子類中的公共成員變量

  2)、獲取父類和子類的成員方法:

1 public static void getMethod() throws ClassNotFoundException { 2     Class<?> son = Class.forName("com.offcn.wh.reflect.son"); 3     Method[] methods = son.getMethods(); 4     for (Method method : methods) { 5  System.out.println(method); 6  } 7 }
  結果如下
    

       根據結果可以看出此方法獲取的是所有“上”類中的方法

    3)、獲取構造方法: 

1 public static void constructor() throws Exception { 2     Class<?> son = Class.forName("com.offcn.wh.reflect.son"); 3     Constructor<?>[] constructors = son.getConstructors(); 4     for (Constructor<?> constructor : constructors) { 5  System.out.println(constructor); 6  } 7 }
  結果如下
    

     根據結果可以看出此方法獲取的是本類的所有構造方法

 
        

 其實能獲取的還有很多,比如本類的接口等等,大家可以嘗試一下,基本上類中有的東西都可以獲取到

2、獲取子類中的私有內容

  通過getDeclaredxxx的方法(又稱為暴力反射)來獲取,比如說變量:

1 public static void getFields() throws ClassNotFoundException { 2     Class<?> son = Class.forName("com.offcn.wh.reflect.son"); 3     Field[] fields = son.getDeclaredFields(); 4     for (Field field : fields) { 5  System.out.println(field); 6  } 7 }
  結果如下
      

    根據結果可以看出此方法獲取的是本類的所有所有屬性  

3、改變子類中的私有內容(以私有屬性為例)   

   我們通過暴力反射獲取了私有內容后會發現根本無法使用,會報如下圖的錯誤:

   代碼:

1 public static void setFields() throws Exception{
2     Class<?> class1 = Class.forName("com.offcn.wh.reflect.Son");
3     Son son = (Son) class1.newInstance();//通過反射拿到對象
4     Field field = class1.getDeclaredField("name");//根據屬性名稱獲取屬性
5     field.set(son, "wh");//與son.setName("wh")相同
6     System.out.println(son.getName());
7 }

   錯誤:

  

  

   這時就需要設置私有屬性的Accessible屬性為true,然后再進行修改

  

 

4、獲取父類中的私有屬性、方法

  在上邊的實例中我們獲取了除父類私有內容外的所有內容,下面我們就來獲取一下父類的私有內容(以私有方法為例)

  getField只能獲取本類和父類中的所有屬性,getDeclaredField只能獲取本類的所有屬性,所以要想獲取父類的私有屬性只有先去獲取父類的字節碼對象

  獲取父類的方法:getSuperclass();

  具體代碼如下:

1 public static void getSuper() throws ClassNotFoundException {
2     Class<?> son = Class.forName("com.offcn.wh.reflect.Son");
3     Class<?> superclass = son.getSuperclass();//獲取父類字節碼對象
4     Field[] fields = superclass.getDeclaredFields();//獲取父類的所有屬性
5     for (Field field : fields) {
6         System.out.println(field);
7     }
8 }

 

5、總結

  我們只要掌握了反射,就可以獲取類的字節碼對象,然后通過方法獲取類中的內容,getxxx()為獲取本類和父類的公共方法,getDeclaredxxx()為獲取本類的所有內容,如果想修改或者使用私有內容,就需要設置xxx.setAccessible(true)來獲取訪問權限,對於父類的私有內容我們可以通過getSuperclass()來獲取父類的字節碼對象,然后再去獲取私有內容。

  我的個人公眾號會不定時更新我的java學習之路,大家如果也在學習java可以在公眾號上邊與我交流哦。


免責聲明!

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



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