9 通过实例深入研究InvocationHandler
先看如下代码:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
public class ProxyDemo4 {
public static void main(String[] args) throws Exception {
//动态生成代理类的Class实例,此代理类实现Collection接口并调用目标类的方法
Class clazzProxy =
Proxy.getProxyClass(Collection. class.getClassLoader(), Collection.class );
System.out.println("--------begin create instance object-------");
//获得此代理类的构造方法
Constructor constructor = clazzProxy.getConstructor(InvocationHandler. class) ;
//生成一个代理类对象,InvocationHandler用匿名内部类。invoke方法封装了要执行的目标代码
Collection proxy = ( Collection)constructor.newInstance( new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null ;
}
});
System.out.println(proxy); //结果:null
proxy.clear(); //执行没有返回值的方法,不会报告异常
proxy.size(); //执行有返回值的方法,会报告空指针异常
System.out.println(proxy.getClass()); //class $Proxy0
}
}
(1)分析上面打印动态类的实例对象时,结果为什么会是null呢?
答:打印动态类的示例对象实际上就是打印proxy的toString方法,也就是执行代理对象中的如下代码:
String toString(){
return handler.invoke(this, this.getClass().getMethod("toString"), null);
}
由于invoke方法返回的是null,打印出来的结果肯定是null。
(2)调用有基本类型返回值的方法时为什么会出现NullPointerException异常?
答:执行proxy.size()方法,就是执行下面的代码:
int size(){
return handler.invoke(this, this.getClass().getMethod("size"), null);
}
由于invoke