說到反射,相信有過程式設計經驗的人都不會陌生。反射機制讓Java變得更加的靈活。反射機制在Java的眾多特性中是非常重要的一個。下面就讓我們一點一點了解它是怎麼一回事。
什麼是反射
在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。
反射有什麼用
1,在執行時判斷任意一個物件所屬的類;
2,在執行時構造任意一個類的物件;
3,在執行時判斷任意一個類所具有的成員變數和方法;
4,在執行時呼叫任意一個物件的方法;
5,生成動態代理。
反射的API
學習一門語言,一種比較好的方式就是看它的API文件,因為它的API是最權威的,最準確的。下面我們一起看看JDK的API對於反射是如何描述的吧!
與反射有關的所有介面以及類都在java.lang.reflect包裡。
介面
介面摘要 |
|
表示目前正在此 VM 中執行的程式的一個已註釋元素。 |
|
GenericArrayType 表示一種陣列型別,其元件型別為引數化型別或型別變數。 |
|
宣告型別變數的所有實體的公共介面。 |
|
InvocationHandler 是代理例項的呼叫處理程式 實現的介面。 |
|
成員是一種介面,反映有關單個成員(欄位或方法)或構造方法的標識資訊。 |
|
ParameterizedType 表示引數化型別,如 Collection<String>。 |
|
Type 是 Java 程式語言中所有型別的公共高階介面。 |
|
TypeVariable 是各種型別變數的公共高階介面。 |
|
WildcardType 表示一個萬用字元型別表示式,如 ?、? extends Number 或 ? super Integer。 |
類
類摘要 |
|
AccessibleObject 類是 Field、Method 和 Constructor 物件的基類。 |
|
Array 類提供了動態建立和訪問 Java 陣列的方法。 |
|
Constructor 提供關於類的單個構造方法的資訊以及對它的訪問許可權。 |
|
Field 提供有關類或介面的單個欄位的資訊,以及對它的動態訪問許可權。 |
|
Method 提供關於類或介面上單獨某個方法(以及如何訪問該方法)的資訊。 |
|
Modifier 類提供了 static 方法和常量,對類和成員訪問修飾符進行解碼。 |
|
Proxy 提供用於建立動態代理類和例項的靜態方法,它還是由這些方法建立的所有動態代理類的超類。 |
|
反射操作的 Permission 類。 |
下面給大家寫了一個小例項:
package reflection; public class UserInfo { private Integer id; private String userName; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString(){ return this.getClass().getName(); } }
package reflection; public class GetClass { public boolean ClassCheck(){ try { System.out.println("第一種,通過類本身獲得物件"); Class UserClass = this.getClass(); System.out.println("第一種方式成功!類名:"+UserClass.toString()+"\n"); System.out.println("第二種,通過子類例項獲取父類"); UserInfo ui = new UserInfo(); UserClass = ui.getClass(); Class SubUserClass = UserClass.getSuperclass(); System.out.println("第二種方式成功!類名:"+SubUserClass.toString()+"\n"); System.out.println("第三種,通過類名加.class獲得物件"); Class ForClass = reflection.UserInfo.class; System.out.println("第三種方式成功!類名:"+ForClass.toString()+"\n"); System.out.println("第四種,通過類名的字串獲得物件"); Class ForName = Class.forName("reflection.UserInfo"); System.out.println("第四種方式成功!類名:"+ForName.toString()+"\n"); } catch (Exception e) { e.printStackTrace(); return false; } return true; } @Override public String toString(){ return this.getClass().getName(); } public static void main(String[] args) { GetClass gc = new GetClass(); gc.ClassCheck(); if (gc.ClassCheck()) { System.out.println("所有反射全部成功!"); } else { System.out.println("反射有問題,請檢查!"); } } }
上面四種方法裡面,我用的最多的是第四種,這種一般都是配合配置檔案一起用的。反射與配置檔案的結合讓我們的程式碼變得非常的靈活,易擴充套件、以維護。可謂是好處多多呀,所以才有那句”反射反射,程式設計師的快樂!“一起盡情的快樂吧!
PS:下一篇將結合例項更加詳細的講解!《菜鳥學程式設計(十)——Java反射機制(二)》