package com.itcast.day3;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.PRoxy;import java.util.ArrayList;import java.util.Collection;/* * 三種得到代理類對象的方式 * 一、直觀型 * 二、匿名內部類型 * 三、從字節碼一步到位型(推薦使用) */public class ProxyTest { public static void main(String[] args)throws Exception { //得到代理類的字節碼 Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); //clazzProxy1.newInstance();//不能這么干,因為該newInstance調用的是那個不帶參數的構造方法 /**一、最直觀的方式創建代理類對象***/ //01.得到有參數的構造方法 System.out.println("begin create instance"); Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class); //newInstance時要有InvocationHandler實例,但是InvocationHandler是一個接口,所以定義了這個類 class InvocationHandlerImpl_1 implements InvocationHandler{ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub return null; } } //02.得到實例對象 Collection proxy1=(Collection) constructor.newInstance(new InvocationHandlerImpl_1()); System.out.println(proxy1.toString());// proxy1.clear();//無返回值函數 //proxy1.size();//有返回值函數--報空指針--沒有目標類 /**二、使用匿名內部類得到代理類對象****/ Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } }); /**三、一步到位得到代理類對象****/ Collection proxy3 = (Collection)Proxy.newProxyInstance( Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler(){ ArrayList target=new ArrayList(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long beginTime=System.currentTimeMillis(); Object reVal=method.invoke(target, args); long endTime=System.currentTimeMillis(); System.out.println(method.getName()+" running "+(endTime-beginTime)); return reVal; } } ); proxy3.add("123"); proxy3.add("456"); System.out.println(proxy3.size()); System.out.println(proxy3.getClass().getName());//com.sun.proxy.$Proxy0,為什么不是ArrayList? //原因 Object沒有把所有的方法都派發給 代理類構造方法的參數---InvocationHandler來處理 /* java.lang.reflect.Proxy API 在代理實例上的 java.lang.Object 中聲明的 hashCode、equals 或 toString 方法的調用將按照與編碼 和指派接口方法調用相同的方式進行編碼,并被指派到調用處理程序的 invoke 方法,如上所述。 傳遞到 invoke 的 Method 對象的聲明類是 java.lang.Object。 代理類不重寫從 java.lang.Object 繼承的代理實例的其他公共方法, 所以這些方法的調用行為與其對 java.lang.Object 實例的操作一樣。 */ }}
新聞熱點
疑難解答