Java的反射與代理

來源:互聯網
上載者:User

標籤:動態擷取   注意   運行   靜態   ceo   實現   設計   好用   目標   

java的類型資訊在運行時如何表示?

    通過Class對象,class類是程式運行期間,為所有的對象維護一個運行時的類型標識,儲存這些資訊的類被稱為class。

    如何擷取類的class對象引用?

        1. Class.forName();forname是class類的靜態方法。

        2. 如果已經有一個對象,可以調用對象的getClass(),此方法屬於根類object。

        3. 使用類字面常量.class;不僅可以用於普通的類,還可以用於介面,數組,以及基礎資料型別 (Elementary Data Type)。

      注意,一個class對象表示一個類型,未必一定是一種類。如Class c = int.class,c不是類,但是一個class類型對象。

    .class和forName()的區別:

        程式中每一個類都有一個class對象,所有的類都是在對其第一次使用時,動態載入到JVM中。當程式建立第一個對類的靜態成員的引用時(構造器也是類的靜態方法),就會載入這個類,然後進行類的靜態初始化。通過.class得到class對象引用,不會觸發類的初始化,而使用forName()會使類進行初始化。

    Class類是泛型的。我們可以用泛型文法,讓編譯器進行額外的類型檢查。

        如 Class<?> intClass = int.class;    Class<House> houseType = House.class;

    我們可以根據得到的class引用,判斷一個對象obj是不是某個Class類型的執行個體(如類名為Base)。

        1. obj instanceof Base

        2. Base.class.isInstance(obj)

    instanceof 和insInstance都保持了類型的概念,即可以識別出繼承的關係。

    

若我們想要在運行時擷取類的資訊呢?在編譯時間不能確定需要的是哪個類,所以.class和getClass()是顯然不好用的。

Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變數和方法;在運行時調用任意一個對象的方法;產生動態代理。

Class類與java.lang.reflect類庫一起對反射的概念進行了支援。

在Class類中:

    Static Class forName(String className)可以得到該類型的對象引用

    Object newInstance()建立該類型執行個體

    預設使用類的無參數構造器,如果建立有參數執行個體,需要先調用getConstructors(),得到一個Constructor構造器的執行個體。

        Eg.e.getClass().newInstance()    e.getConstructor(String.class).newInstance(“233”)

    Field[] getFields()

    Method[] getMethods()

    Constructor[] getConstructors()

java.lang.reflect類庫中有三個類:
    Field:描述類的域

    Method:描述類的方法

    Constructor:描述類的構造器

在method類中:

Public Object invoke(Object implicitPara,Object[] explicitPara) 調用任意方法。

通過這些類庫中類的方法可以實現動態擷取類型資訊。


代理是基本的設計模式之一,代理通常充當著中間人的身份。一個對象不想或者不能直接引用另一個對象,而代理對象可以在用戶端和目標對象之間起到中介的作用。

靜態代理:寫在代碼裡,通過中間類去操作實際類,也就是被代理的類

動態代理:動態地建立代理,動態地實現對實際類的調用。

 

反射和java.lang.reflect.Proxy等相關類實現了動態代理。

動態代理分為3個步驟:

    1. 建立委託類,即被代理的類,建立Interface介面和實作類別;

    2. 建立實現了InvocationHandler介面的代理類,在invoke()內執行代理操作;

    3. 建立代理對象,將代理對象傳遞給調用者。

通過調用proxy的靜態方法newProxyInstance()建立動態代理,

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

這個方法需要三個參數:

    1. ClassLoader loader指明組建代理程式對象使用的類裝載器

    2. Class<?>[] interfaces指定代理器實現的介面列表

    3. InvocationHandler h指明Invocation介面的一個實現,就是定義的代理類要做的事情。

通過動態代理,不管調用代理對象的什麼方法,都是調用代理器的invoke方法,在這裡人為地決定了如何調用被代理對象的原始方法,如何進行額外的處理。相當於對被代理對象直接方法調用的攔截。


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.