菜鳥學Java(十四)——Java反射機制(一)

劉水鏡發表於2013-11-06

說到反射,相信有過程式設計經驗的人都不會陌生。反射機制讓Java變得更加的靈活。反射機制在Java的眾多特性中是非常重要的一個。下面就讓我們一點一點了解它是怎麼一回事。


什麼是反射

在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。


反射有什麼用

1,在執行時判斷任意一個物件所屬的類;

2,在執行時構造任意一個類的物件;

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

4,在執行時呼叫任意一個物件的方法;

5,生成動態代理。


反射的API

學習一門語言,一種比較好的方式就是看它的API文件,因為它的API是最權威的,最準確的。下面我們一起看看JDK的API對於反射是如何描述的吧!


與反射有關的所有介面以及類都在java.lang.reflect包裡。


介面

介面摘要

AnnotatedElement

表示目前正在此 VM 中執行的程式的一個已註釋元素。

GenericArrayType

GenericArrayType 表示一種陣列型別,其元件型別為引數化型別或型別變數。

GenericDeclaration

宣告型別變數的所有實體的公共介面。

InvocationHandler

InvocationHandler 是代理例項的呼叫處理程式 實現的介面。

Member

成員是一種介面,反映有關單個成員(欄位或方法)或構造方法的標識資訊。

ParameterizedType

ParameterizedType 表示引數化型別,如 Collection<String>。

Type

Type 是 Java 程式語言中所有型別的公共高階介面。

TypeVariable<D extends GenericDeclaration>

TypeVariable 是各種型別變數的公共高階介面。

WildcardType

WildcardType 表示一個萬用字元型別表示式,如 ?、? extends Number 或 ? super Integer。


類摘要

AccessibleObject

AccessibleObject 類是 Field、Method 和 Constructor 物件的基類。

Array

Array 類提供了動態建立和訪問 Java 陣列的方法。

Constructor<T>

Constructor 提供關於類的單個構造方法的資訊以及對它的訪問許可權。

Field

Field 提供有關類或介面的單個欄位的資訊,以及對它的動態訪問許可權。

Method

Method 提供關於類或介面上單獨某個方法(以及如何訪問該方法)的資訊。

Modifier

Modifier 類提供了 static 方法和常量,對類和成員訪問修飾符進行解碼。

Proxy

Proxy 提供用於建立動態代理類和例項的靜態方法,它還是由這些方法建立的所有動態代理類的超類。

ReflectPermission

反射操作的 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反射機制(二)》

 

 

 

相關文章