今天主要來談一談反射中獲取成員方法和成員變量的主要方法:
在獲取之前我們首先創造兩個類
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可以在公眾號上邊與我交流哦。