Java反射機制(獲取Class對象的三種方式+獲取Class中的構造函數進行對象的初始化+獲取反射類的字段+獲取反射類的一般方法)


  反射技術其實就是動態加載一個指定的類,並獲取該類中的所有內容。而且將字節碼文件封裝成對象,並將字節碼文件中的內容都封裝成對象,這樣便於操作這些成員,簡單來說:反射技術可以對一個類進行解剖,反射大大增強了應用程序的可擴展性。

      反射技術的原理如下圖所示:

但是要想要對字節碼文件進行解剖,必須要有字節碼文件對象. 如何獲取字節碼文件對象呢?

要讀取的類文件源碼:

 

 1 package Reflect;
 2 
 3 public class Person {
 4 
 5     /**
 6      * @param args
 7      */
 8     private String name;
 9     private int age;
10     public Person(){
11         System.out.println("Construcor run..");
12     }
13     public Person(String name,int age){
14     this.name=name;
15     this.age=age;
16     System.out.println("Person param run...");
17     }
18     public static void method(){
19         System.out.println("method run...");
20     }
21     public static void paramMethod(String name,int age){
22         System.out.println("name="+name+"age:"+age);
23     }
24     public static void staticMethod(){
25         System.out.println("static run");
26     }
27     public void show(){
28         System.out.println(name+"Method show run.."+age);
29     }
30 
31 }

 

獲取字節碼文件對象有三種方式:

(1)
 /*
  * 獲取字節碼對象的方式:
  * 1,Object類中的getClass()方法的。
  * 想要用這種方式,必須要明確具體的類,並創建對象。
  * 麻煩 
  */

1 public static void getObject_1() {
2         Person p=new Person();
3         Class<? extends Person> classz=p.getClass();
4         System.out.println(classz);
5         Person p1=new Person();
6         Class<? extends Person> classz1=p.getClass();
7         System.out.println(classz1);
8         System.out.println(classz==classz1);
9     }

(2)
 /*
  * 方式二:
  * 任何數據類型(基本數據類型和引用數據類型)都具備一個靜態的屬性.class來獲取其對應的Class對象。
  * 相對簡單,但是還是要明確用到類中的靜態成員。
  * 還是不夠擴展。
  *
  */

1 public  static void getObject_2() {
2     
3         Class classz=Person.class;
4         Class classz1=Person.class;
5         System.out.println(classz==classz1);
6     }

(3)

 /*
  * 方式三:
  * 只要通過給定的類的 字符串名稱就可以獲取該類,更為擴展。
  * 可是用Class類中的方法完成。
  * 該方法就是forName.
  * 這種方式只要有名稱即可,更為方便,擴展性更強。
  */

1 public  static void getObject_3() throws ClassNotFoundException {
2         String classname="Reflect.Person";
3         Class classz=Class.forName(classname);
4         System.out.println(classz);
5     }

獲取Class中的構造函數初始化對象:

(1)調用空參數的構造函數:使用Class類中的newInstance()方法

 //早期:new時候,先根據被new的類的名稱找尋該類的字節碼文件,並加載進內存,
  // 並創建該字節碼文件對象,並接着創建該字節文件的對應的Person對象.

1   //現在:
2   String name = "cn.itcast.bean.Person";
3   //找尋該名稱類文件,並加載進內存,並產生Class對象。
4   Class clazz = Class.forName(name);
5   //如何產生該類的對象呢?
6   Object obj  = clazz.newInstance();

(2)調用帶參數的構造函數:先要獲取指定參數列表的構造函數對象,然后通過該構造函數的對象的newInstance(實際參數)進行對象的初始化

/*
   * 當獲取指定名稱對應類中的所體現的對象時,
   * 而該對象初始化不使用空參數構造該怎么辦呢?
   * 既然是通過指定的構造 函數進行對象的初始化,
   * 所以應該先獲取到該構造函數。 通過字節碼文件對象即可完成。
   * 該方法是:getConstructor(paramterTypes);
   * 
   */

 

1 //帶參數初始化新創建的對象
2     public  static void createNewObject_param() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
3         String classname="Reflect.Person";
4         Class classz=Class.forName(classname);
5         Constructor constructor=classz.getConstructor(String.class,int.class);
6         constructor.newInstance("Java",30);
7     }

 獲取反射類的字段:

 1     public static void getFiledDemo() throws ClassNotFoundException,
 2             NoSuchFieldException, SecurityException, InstantiationException,
 3             IllegalAccessException {
 4         Class classz = Class.forName("Reflect.Person");
 5         Field field = null;
 6         field = classz.getDeclaredField("age");
 7         field.setAccessible(true);
 8         Object obj = classz.newInstance();
 9         field.set(obj, 89);
10         Object o = field.get(obj);
11         System.out.println(o);
12     }

獲取反射類的成員方法:

(1)獲取空參數一般方法

 1 private static void getMethodDemo_2() throws Exception {
 2         Class clazz = Class.forName("Reflect.Person");
 3 
 4         Method method = clazz.getMethod("show", null);// 獲取空參數一般方法。
 5 
 6         // Object obj = clazz.newInstance();
 7         Constructor constructor = clazz.getConstructor(String.class, int.class);
 8         Object obj = constructor.newInstance("linux", 37);
 9 
10         method.invoke(obj, null);
11     }

(2)獲取帶參數的一般方法

 1 private static void getMethodDemo_3() throws Exception {
 2 
 3         Class clazz = Class.forName("Reflect.Person");
 4 
 5         Method method = clazz.getMethod("paramMethod", String.class, int.class);
 6 
 7         Object obj = clazz.newInstance();
 8 
 9         method.invoke(obj, "Ruby", 89);
10     }


(3)獲取反射類的公有、私有方法

1 private static void getMethodDemo() throws ClassNotFoundException {
2         Class classz = Class.forName("Reflect.Person");
3         Method[] methods = classz.getMethods();// 獲取反射類中所有共有的方法
4         methods = classz.getDeclaredMethods();// 獲取本類中包括私有的所有的方法
5         for (Method method : methods) {
6             System.out.println(method);
7         }
8     }

 


本文為博主原創文章,轉載請注明出處:http://www.cnblogs.com/ysw-go/
1、本博客的原創原創文章,都是本人平時學習所做的筆記,如有錯誤,歡迎指正。
2、如有侵犯您的知識產權和版權問題,請通知本人,本人會即時做出處理文章。
3、本博客的目的是知識交流所用,轉載自其它博客或網站,作為自己的參考資料的,感謝這些文章的原創人員


免責聲明!

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



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