黑马程序员------代理类中invoke方法注意点
---------------------- android培训、java培训、期待与您交流! ----------------------
??Collection proxy1 = (Collection )constructor.newInstance(new MyInvocationHandler1());//方法一
??????? System.out.println(proxy1);//打印出null,是因为java.lang.Object把toString方法委托给了代理类对象的invoke方法
??
??final ArrayList target = new ArrayList();//内部类调用外部的变量时,变量需用final修饰
??????? Collection proxy3 = (Collection)getProxy(target,new MyAdvice());//方法三
??????? System.out.println(proxy3.size());
??????? System.out.println(proxy3.getClass().getName());//打印正确,getClass方法没有委托给代理类对象的invoke方法,
??????? ????????????//java.lang.Object只把hashCode、equals 或 toString 方法委托给了代理类
??--------------------------------------------------------------------------
package HEIMA_Proxy;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.Collection;public class ProxyTest { /** * <p>メソッドの機能概要を記述してください.</p> * * @param args * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalAccessException * @throws InstantiationException * @throws IllegalArgumentException */ public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); System.out.println(clazzProxy1.getName()); System.out.println("---begin constructors lis---"); //一下方法取得该类的各个构造方法 Constructor[] constructors = clazzProxy1.getConstructors(); for(Constructor constructor:constructors){ String name = constructor.getName(); StringBuilder sBuilder = new StringBuilder(name);//StringBuilder与StringBuffer的区别,StringBuilder在单线程是效率高, //多线程时选用StringBuffer sBuilder.append('('); Class []clazzParameters = constructor.getParameterTypes(); for(Class clazzParameter : clazzParameters){ sBuilder.append(clazzParameter.getName()).append(','); } if(clazzParameters.length!=0 && clazzParameters!=null) sBuilder.deleteCharAt(sBuilder.length()-1); sBuilder.append(')'); System.out.println(sBuilder.toString()); } System.out.println("---begin methods lis---"); //以下方法取得该类的各个成员方法 Method[] methods = clazzProxy1.getMethods(); for(Method method:methods){ String name = method.getName(); StringBuilder sBuilder = new StringBuilder(name);//StringBuilder与StringBuffer的区别,StringBuilder在单线程是效率高, //多线程时选用StringBuffer sBuilder.append('('); Class []clazzParameters = method.getParameterTypes(); for(Class clazzParameter : clazzParameters){ sBuilder.append(clazzParameter.getName()).append(','); } if(clazzParameters.length!=0 && clazzParameters!=null) sBuilder.deleteCharAt(sBuilder.length()-1); sBuilder.append(')'); System.out.println(sBuilder.toString()); } System.out.println("---begin create instance object---"); //以下为创建对象// clazzProxy1.newInstance();//报错,因为Proxy代理类没有无参构造方法 Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class); class MyInvocationHandler1 implements InvocationHandler{ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub return null; } } Collection proxy1 = (Collection )constructor.newInstance(new MyInvocationHandler1());//方法一 System.out.println(proxy1);//打印出null,是因为java.lang.Object把toString方法委托给了代理类对象的invoke方法 proxy1.clear();//调用动态类proxy的无返回值方法不会报错// proxy1.size();//调用动态类proxy的有返回值的方法会报错 Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){//这里是个匿名内部类 //以上直接new接口+{}并加上抽象方法直接实例一个InvocationHandler的子类(匿名内部类) @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub return null; } }); final ArrayList target = new ArrayList();//内部类调用外部的变量时,变量需用final修饰 Collection proxy3 = (Collection)getProxy(target,new MyAdvice());//方法三 proxy3.add("zxx"); proxy3.add("lhm"); proxy3.add("bxd"); System.out.println(proxy3.size()); System.out.println(proxy3.getClass().getName());//getClass方法没有委托给代理类对象的invoke方法, //java.lang.Object只把hashCode、equals 或 toString 方法委托给了代理类 } private static Object getProxy(final Object target,final MyAdvice advice) {//注意!!!!因为形参需被匿名内部类调用所以用final修饰 Object proxy3 = Proxy.newProxyInstance(//方法三 target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler(){//这里是个参数(匿名内部类) @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // long beginTime = System.currentTimeMillis(); advice.beforeMethod(); Object retVal = method.invoke(target, args);// long endTime = System.currentTimeMillis();// System.out.println(method.getName()+"花费时间:"+(endTime-beginTime)); advice.afterMethod(method); return retVal; } } ); return proxy3; }}
?
---------------------- android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima
?