Java動態代理 - 注意點

  • 如果實現的接口是non-public的。那麼接口跟proxy class必須在同一個包裏。

  • 如果在不同接口中有相同的Method signature,當有一個的反回類型是void或primitive type時,其他的必須一樣。如果不是上敘情況,那麼其中必須有一個類型是可以assign給其他類型的。

  • 實現的接口數是由虛擬機決定的,最大樹是65535。

  • 接口的排列順序是很重要的。不同的順序生成不同的proxy class。

  • 只能實現interfaces, 不能是類。所以傳遞給Proxy API的interfaces參數的 Class objects 不能是classes 或 primitive types.

  • 所有待代理的接口必須對制定的classloader可見。 即Class.forName(i.getName(),false,cl) == i

  • Proxy API有cache機制。cache裏的proxy class 被class loaders跟interface list指定。

  • Proxy class是public , final 並且是非abstract的。

  • Proxy class extend java.lang.reflect.Proxy

  • Proxy class類名以“$Proxy”開始。

  • 每一個proxy 實例都有一個對應的invocation handler 對象。

  • 傳遞invocation handler 的invoke的其中一個參數是方法調用的實際參數,其中的primitive type會被裝箱成相應的類型,如java.lang.Integer....

  • 如果proxy實例的method的返回類型是primitive type。但在invocation Hanlder中返回null會throw nullpointException。在invocation handler中都是返回object,所以null在拆箱時會異常。

  • hashCode, equals, toString都會傳遞到invocation handler執行。

  • 當多個interface聲明有同一Method時。當我們調用proxy 實例的這個Method, 傳遞給invocation handler invoke的Method Object將是排在最前的那個interface的method object。例外的是hashCode, equals, toString這三個,他們的Method object是java.lang.Object上聲明的Method。

  • 當多個interface聲明有同一Method時。throw 的exception可以是其中任意一個的throws。如果都找不到就throw UndeclaredThrowableException。

  • java.lang.reflect.Proxy是實現了Serializable的。但是,如果invocation hanlder沒有實現Serializable,我們用ObjectOutputStream來傳遞proxy實例時也會異常。實現Externalizable接口是沒用的,因爲proxy實例是不會調用writeExternal跟readExternal的。

  • 如果proxy class沒有serializable 字段或serialVersionUID是0L。 proxy class上的static 的lookup method將會返回我們不期望的值。 getFields返回長度爲0的數組。 getField返回null String。

  • 發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章