JDK动态代理之InvocationHandler接口源码分析

JDK动态代理之InvocationHandler接口源码分析

InvacationHandler类是JDK动态代理中需要实现的接口,接口中只有一个方法:invoke

代码

package java.lang.reflect;

/**
 * {@code InvocationHandler} is the interface implemented by
 * the invocation handler of a proxy instance.
 *
 * 译文:
 *  InvocationHandler是代理类实现的接口
 *
 * 

Each proxy instance has an associated invocation handler. * When a method is invoked on a proxy instance, the method * invocation is encoded and dispatched to the {@code invoke} * method of its invocation handler. * * 译文: * 每个代理对象都有一个与之关联的handler,代理对象上方法调用会被编码,并发送到 * 与之对应的handler上 */ public interface InvocationHandler { /** * Processes a method invocation on a proxy instance and returns * the result. This method will be invoked on an invocation handler * when a method is invoked on a proxy instance that it is * associated with. * * 译文: * 处理代理类上的方法调用并返回结果。代理类的方法调用将同步调用与之相关联的handler * * @param proxy the proxy instance that the method was invoked on * * 入参:proxy:承载被调用的方法的代理类实例 * * @param method the {@code Method} instance corresponding to * the interface method invoked on the proxy instance. The declaring * class of the {@code Method} object will be the interface that * the method was declared in, which may be a superinterface of the * proxy interface that the proxy class inherits the method through. * * 入参:method:代理类实例上实现的接口的方法 * * * @param args an array of objects containing the values of the * arguments passed in the method invocation on the proxy instance, * or {@code null} if interface method takes no arguments. * Arguments of primitive types are wrapped in instances of the * appropriate primitive wrapper class, such as * {@code java.lang.Integer} or {@code java.lang.Boolean}. * * 入参:args: 代理类实例上的被调用方法的参数,为一个object数组, * 当被调用的方法无入参时,args为null,基本类型的参数将会 * 被其相应的包装类型的参数转换,比如int会被转换成Integer, * boolean会被转换成Boolean * * @return the value to return from the method invocation on the * proxy instance. If the declared return type of the interface * method is a primitive type, then the value returned by * this method must be an instance of the corresponding primitive * wrapper class; otherwise, it must be a type assignable to the * declared return type. If the value returned by this method is * {@code null} and the interface method's return type is * primitive, then a {@code NullPointerException} will be * thrown by the method invocation on the proxy instance. If the * value returned by this method is otherwise not compatible with * the interface method's declared return type as described above, * a {@code ClassCastException} will be thrown by the method * invocation on the proxy instance. * * 返回值:Object:代理类实力上被调用的方法的返回值。 * 如果原方法定义的返回值为基本数据类型,则返回值将会被相应地 * 转换成对应的包装类型。否则就必须是无需转换但是却能被重新定义的、 * (比如String类型)。如果原接口方法定义的返回值为基本数据类型,但是 * 代理类实例上被调用的方法返回了null,则会抛出异常(NullPointerException), * 如果方法返回的数据与接口定义的方法的返回值不兼容,则会抛出 * ClassCastException异常。 * * * * @throws Throwable the exception to throw from the method * invocation on the proxy instance. The exception's type must be * assignable either to any of the exception types declared in the * {@code throws} clause of the interface method or to the * unchecked exception types {@code java.lang.RuntimeException} * or {@code java.lang.Error}. If a checked exception is * thrown by this method that is not assignable to any of the * exception types declared in the {@code throws} clause of * the interface method, then an * {@link UndeclaredThrowableException} containing the * exception that was thrown by this method will be thrown by the * method invocation on the proxy instance. * * @see UndeclaredThrowableException */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }

总结:

  1. 方法的参数分别是:代理类,被调用的方法,被调用的方法的参数(接口方法无参数时args为null)
  2. 方法的返回值只会返回相应的包装类,比如int会被转换成Integer
  3. 如果接口方法定义的返回值是基本数据类型,但是代理类实例调用方法时,结果为null,则会有代理类实例抛出空指异常
  4. 如果接口定义的方法返回值和代理类实例调用方法 返回值不兼容,则会抛出ClassCast异常,比如Object向下强转为int,但是Object是double向上转的,则会报错。
  5. JDK动态代理必须要实现接口。
  6. 被代理的接口的方法,返回值最好定义为包装类,这样就算代理类实例返回null,也不会影响程序正常运行。

你可能感兴趣的:(java源码)