1. 如果实现的接口是non-public的。那么接口跟proxy class必须在同一个包里。

  2. 如果在不同接口中有相同的Method signature,当有一个的反回类型是void或primitive type时,其他的必须一样。如果不是上叙情况,那么其中必须有一个类型是可以assign给其他类型的。

  3. 实现的接口数是由虚拟机决定的,最大树是65535。

  4. 接口的排列顺序是很重要的。不同的顺序生成不同的proxy class。

  5. 只能实现interfaces, 不能是类。所以传递给Proxy API的interfaces参数的 Class objects 不能是classes 或 primitive types.

  6. 所有待代理的接口必须对制定的classloader可见。 即Class.forName(i.getName(),false,cl) == i

  7. Proxy API有cache机制。cache里的proxy class 被class loaders跟interface list指定。

  8. Proxy class是public , final 并且是非abstract的。

  9. Proxy class extend java.lang.reflect.Proxy

  10. Proxy class类名以“$Proxy”开始。

  11. 每一个proxy 实例都有一个对应的invocation handler 对象。

  12. 传递invocation handler 的invoke的其中一个参数是方法调用的实际参数,其中的primitive type会被装箱成相应的类型,如java.lang.Integer....

  13. 如果proxy实例的method的返回类型是primitive type。但在invocation Hanlder中返回null会throw nullpointException。在invocation handler中都是返回object,所以null在拆箱时会异常。

  14. hashCode, equals, toString都会传递到invocation handler执行。

  15. 当多个interface声明有同一Method时。当我们调用proxy 实例的这个Method, 传递给invocation handler invoke的Method Object将是排在最前的那个interface的method object。例外的是hashCode, equals, toString这三个,他们的Method object是java.lang.Object上声明的Method。

  16. 当多个interface声明有同一Method时。throw 的exception可以是其中任意一个的throws。如果都找不到就throw UndeclaredThrowableException。

  17. java.lang.reflect.Proxy是实现了Serializable的。但是,如果invocation hanlder没有实现Serializable,我们用ObjectOutputStream来传递proxy实例时也会异常。实现Externalizable接口是没用的,因为proxy实例是不会调用writeExternal跟readExternal的。

  18. 如果proxy class没有serializable 字段或serialVersionUID是0L。 proxy class上的static 的lookup method将会返回我们不期望的值。 getFields返回长度为0的数组。 getField返回null String。