Java中的反射機制

來源:互聯網
上載者:User

標籤:string   靜態   one   wan   語言   from   運行   工作   des   

Java反射的概念

Java反射機制是在運行狀態中,對於任意一個,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態擷取的資訊以及動態調用對象的方法的功能稱為Java語言的反射機制

Java反射機制主要提供下面幾種用途:

1.在運行時判斷任意一個對象所屬的類

2.在運行時構造任意一個類的對象

3.在運行時判斷任意一個類所具有的成員變數和方法

4.在運行時調用任意一個對象的方法

首先看一個簡單的例子,通過這個例子來理解Java的反射機制是如何工作的

import java.lang.reflect.Method;/** * Java 反射練習。 *  * @author Wanggc */public class ForNameTest {    /**     * 入口函數。     *      * @param args     *            參數     * @throws Exception     *             錯誤資訊     */    public static void main(String[] args) throws Exception {        // 獲得Class        Class<?> cls = Class.forName(args[0]);        // 通過Class獲得所對應對象的方法        Method[] methods = cls.getMethods();        // 輸出每個方法名        for (Method method : methods) {            System.out.println(method);        }    }}
程式碼範例如下

使用java的反射機制,一般需要遵循三步:

1.獲得你想操作類的Class對象

2.通過第一步獲得的Class對象去取得操作類的方法或是屬性名稱

3.操作第二步取得的方法或是屬性

 Java啟動並執行時候,某個類無論產生多少個對象,他們都會對應同一個Class對象,它表示正在運行程式中的類和介面。如何取得操作類的Class對象,常用的有三種方式:

1.調用Class的靜態方法forName,如上例;

2.使用類的.class文法,如:Class<?> cls = String.class;

3.調用對象的getClass方法,如:String str = "abc";Class<?> cls = str .getClass();

下面將通過執行個體講述如何通過前面所訴的三步來執行某對象的某個方法:

 3 import java.lang.reflect.Method; 4  5 /** 6  * Java 反射練習。 7  *  8  * @author Wanggc 9  */10 public class ReflectionTest {11     public static void main(String[] args) throws Exception {12         DisPlay disPlay = new DisPlay();13         // 獲得Class14         Class<?> cls = disPlay.getClass();15         // 通過Class獲得DisPlay類的show方法16         Method method = cls.getMethod("show", String.class);17         // 調用show方法18         method.invoke(disPlay, "Wanggc");19     }20 }21 22 class DisPlay {23     public void show(String name) {24         System.out.println("Hello :" + name);25     }26 }
程式碼範例如下

 上例講述了如何通過反射調用某個類的方法,下面將再通過一個執行個體講述如何通過反射給某個類的屬性賦值:

  3 import java.lang.reflect.Field;  4   5 /**  6  * Java 反射之屬性練習。  7  *   8  * @author Wanggc  9  */ 10 public class ReflectionTest { 11     public static void main(String[] args) throws Exception { 12         // 建立學生對象 13         Student student = new Student(); 14         // 為學生對象賦值 15         student.setStuName("Wanggc"); 16         student.setStuAge(24); 17         // 建立拷貝目標對象 18         Student destStudent = new Student(); 19         // 拷貝學生對象 20         copyBean(student, destStudent); 21         // 輸出拷貝結果 22         System.out.println(destStudent.getStuName() + ":" 23                 + destStudent.getStuAge()); 24     } 25  26     /** 27      * 拷貝學生對象資訊。 28      *  29      * @param from 30      *            拷貝來源物件 31      * @param dest 32      *            拷貝目標對象 33      * @throws Exception 34      *             例外 35 */ 36     private static void copyBean(Object from, Object dest) throws Exception { 37         // 取得拷貝來源物件的Class對象 38         Class<?> fromClass = from.getClass(); 39         // 取得拷貝來源物件的屬性列表 40         Field[] fromFields = fromClass.getDeclaredFields(); 41         // 取得拷貝目標對象的Class對象 42         Class<?> destClass = dest.getClass(); 43         Field destField = null; 44         for (Field fromField : fromFields) { 45             // 取得拷貝來源物件的屬性名稱字 46             String name = fromField.getName(); 47             // 取得拷貝目標對象的相同名稱的屬性 48             destField = destClass.getDeclaredField(name); 49             // 設定屬性的可訪問性 50             fromField.setAccessible(true); 51             destField.setAccessible(true); 52             // 將拷貝來源物件的屬性的值賦給拷貝目標對象相應的屬性 53             destField.set(dest, fromField.get(from)); 54         } 55     } 56 } 57  58 /** 59  * 學生類。 60  */ 61 class Student { 62     /** 姓名 */ 63     private String stuName; 64     /** 年齡 */ 65     private int stuAge; 66  67     /** 68      * 擷取學生姓名。 69      *  70      * @return 學生姓名 71 */ 72     public String getStuName() { 73         return stuName; 74     } 75  76     /** 77      * 設定學生姓名 78      *  79      * @param stuName 80      *            學生姓名 81 */ 82     public void setStuName(String stuName) { 83         this.stuName = stuName; 84     } 85  86     /** 87      * 擷取學生年齡 88      *  89      * @return 學生年齡 90 */ 91     public int getStuAge() { 92         return stuAge; 93     } 94  95     /** 96      * 設定學生年齡 97      *  98      * @param stuAge 99      *            學生年齡100 */101     public void setStuAge(int stuAge) {102         this.stuAge = stuAge;103     }104 }
程式碼範例如下

前面講述了如何用Java反射機制操作一個類的方法和屬性,下面再通過一個執行個體講述如何在運行時建立類的一個對象:

 3 import java.lang.reflect.Field; 4  5 /** 6  * Java 反射之屬性練習。 7  *  8  * @author Wanggc 9  */10 public class ReflectionTest {11     public static void main(String[] args) throws Exception {12         // 建立學生對象13         Student student = new Student();14         // 為學生對象賦值15         student.setStuName("Wanggc");16         student.setStuAge(24);17         // 建立拷貝目標對象18         Student destStudent = (Student) copyBean(student);19         // 輸出拷貝結果20         System.out.println(destStudent.getStuName() + ":"21                 + destStudent.getStuAge());22     }23 24     /**25      * 拷貝學生對象資訊。26      * 27      * @param from28      *            拷貝來源物件29      * @param dest30      *            拷貝目標對象31      * @throws Exception32      *             例外33 */34     private static Object copyBean(Object from) throws Exception {35         // 取得拷貝來源物件的Class對象36         Class<?> fromClass = from.getClass();37         // 取得拷貝來源物件的屬性列表38         Field[] fromFields = fromClass.getDeclaredFields();39         // 取得拷貝目標對象的Class對象40         Object ints = fromClass.newInstance();41         for (Field fromField : fromFields) {42             // 設定屬性的可訪問性43             fromField.setAccessible(true);44             // 將拷貝來源物件的屬性的值賦給拷貝目標對象相應的屬性45             fromField.set(ints, fromField.get(from));46         }47 48         return ints;49     }50 }51 52 /**53  * 學生類。54  */55 class Student {56     /** 姓名 */57     private String stuName;58     /** 年齡 */59     private int stuAge;60 61     /**62      * 擷取學生姓名。63      * 64      * @return 學生姓名65 */66     public String getStuName() {67         return stuName;68     }69 70     /**71      * 設定學生姓名72      * 73      * @param stuName74      *            學生姓名75 */76     public void setStuName(String stuName) {77         this.stuName = stuName;78     }79 80     /**81      * 擷取學生年齡82      * 83      * @return 學生年齡84 */85     public int getStuAge() {86         return stuAge;87     }88 89     /**90      * 設定學生年齡91      * 92      * @param stuAge93      *            學生年齡94 */95     public void setStuAge(int stuAge) {96         this.stuAge = stuAge;97     }98 }
程式碼範例如下

補充:在獲得類的方法、屬性、建構函式時,會有getXXX和getgetDeclaredXXX兩種對應的方法。之間的區別在於前者返回的是存取權限為public的方法和屬性,包括父類中的;但後者返回的是所有存取權限的方法和屬性,不包括父類的

 

Java中的反射機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.