如果實現的接口是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。