反射的做用:經過反射獲取屬性和方法

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

在獲取以前咱們首先創造兩個類java

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類(子類):this

 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(反射)的三種方式以及獲取對應對象的一個方法:spa

 

 

咱們能夠經過上述三種方法獲取相對應的class,若是想要經過class獲取對應的對象,就須要用newInstance方法:3d

    

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

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

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 }
  結果以下
    

       根據結果能夠看出此方法獲取的是全部「上」類中的方法blog

    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 }
  結果以下
    

     根據結果能夠看出此方法獲取的是本類的全部構造方法

 

 其實能獲取的還有不少,好比本類的接口等等,你們能夠嘗試一下,基本上類中有的東西均可以獲取到

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

  經過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 }
  結果以下
      

    根據結果能夠看出此方法獲取的是本類的全部全部屬性  

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

   咱們經過暴力反射獲取了私有內容後會發現根本沒法使用,會報以下圖的錯誤:

   代碼:

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,而後再進行修改

  

 

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

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

  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 }

 

五、總結

  咱們只要掌握了反射,就能夠獲取類的字節碼對象,而後經過方法獲取類中的內容,getxxx()爲獲取本類和父類的公共方法,getDeclaredxxx()爲獲取本類的全部內容,若是想修改或者使用私有內容,就須要設置xxx.setAccessible(true)來獲取訪問權限,對於父類的私有內容咱們能夠經過getSuperclass()來獲取父類的字節碼對象,而後再去獲取私有內容。

  個人我的公衆號會不定時更新個人java學習之路,你們若是也在學習java能夠在公衆號上邊與我交流哦。

原文出處:https://www.cnblogs.com/apbddpz/p/11255182.html

相關文章
相關標籤/搜索