黑马程序员_JAVA学习笔记10
来源:互联网 发布:win7网络和共享打不开 编辑:程序博客网 时间:2024/06/06 19:03
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
代理模式:
JAVA动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
1.Interface InvocationHandle该接口中仅定义了一个方法:public object invoke(Object obj,Method method,Object[] args)
在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。
2.Proxy:该类即为动态代理类,作用类似于上例中的proxySubject
下面是利用代理动态生成类对象。上面构造方法中要接收一个带invocationHander的参数,所以紧跟着要实现这个接口。然后才可newInstance。上面调用 size方法时会发生错误, 原因可以在下面一段代码中找, 因为 我调用 size方法,但size方法的返回值为int ,但Invoke返回的确是 Null所以就会发生错误。
Class clazzprox = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
Constructor[] constructors = clazzprox.getConstructors();
for(Constructor c : constructors)
{
String name = c.getName();
StringBuilder s = new StringBuilder(name);
s.append("(");
Class[] p = c.getParameterTypes();
for(Class cla : p)
{
s.append(cla.getName()).append(",");
}
s.append(")");
System.out.println(s);
}
}
Constructor constructor = clazzProxy1.getConstructor
class MyInvocationHander1 implements InvocationHandle{
public Object invoke(Object proxy, Method method) throws Throwable{
return null;
}
}
collection proxy1 = (Collection)constructor.newInstance();
System.out.println(proxy1);
proxy1.clear();
让JVM创建动态类及其实例对象,需要给它提供的信息如下:
1.生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知;
2.产生的类字节码必须有个一个关联的类加载器对象;
3.生成的类中的方法的代码是怎样的,也得由我们提供。把我们的代码写在一个约定好了接口对象的方法中,把对象传给它,它调用我的方法,即相当于插入我的代码。提供执行代码的对象就是那个InvocationHandler对象,它是在创建动态类的实例对象的构造方法时传递进去的。在上面的InvocationHandler对象的invoke方法中加一点代码,就可以看到这些代码被调用运行了。
用Proxy.newInstance方法直接一步就创建出代理对象。
最后 可以 用Proxy.newInstance 方法直接创建对象,不用向上面那样麻烦了。
//用Proxy.newProxyInstance()方法,直接动态创建类
Collection c3 = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler(){
//放在这里面 就不是 每次创建 一个arrayList对象了。
//ArrayList al = new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
ArrayList al = new ArrayList();
long beginTime = System.currentTimeMillis();
Object o = method.invoke(al, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " time: "+
(endTime - beginTime));
return o;
}
});
c3.add("aaa");
c3.add("bbb");
c3.add("ccc");
System.out.println(c3.size());
输出结果:
add time: 0
add time: 0
add time: 0
size time: 0
0
这是上面代码的输出结果,为什么会输出 0 ? 因为每add 或 调用size 方法时,就会去调用invoke方法,而arrayList是在invoke方法里面new 出来的,所以每次都是不同的对象,所以 size为0, 如果把new arrayList 方法类里面结果就会输出 3 。
Proxy 从objectg 身上继承的方法 , 只有 hashCode,equals,toString 会给InvocationHanderl 自己,所以上面打印对象时,由于返回值是null 所以才会打印null。其他的方法 都有实现 。
总结动态代理的步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
2.创建被代理的类以及接口。
3.通过Proxy的静态方法newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler);创建一个代理。
4.通过代理调用方法。
- 黑马程序员_java学习笔记10
- 黑马程序员_JAVA学习笔记10
- 黑马程序员_java学习笔记
- 黑马程序员_JAVA 学习笔记23 WEB篇10
- 黑马程序员_java基础学习笔记10_多线程
- 黑马程序员_Java高新技术部分学习笔记
- 黑马程序员_java学习笔记四
- 黑马程序员_java学习笔记01
- 黑马程序员_java学习笔记02
- 黑马程序员_java学习笔记03
- 黑马程序员_java学习笔记04
- 黑马程序员_java学习笔记05
- 黑马程序员_java学习笔记06
- 黑马程序员_java学习笔记07
- 黑马程序员_java学习笔记08
- 黑马程序员_java学习笔记09
- 黑马程序员_java学习笔记11
- 黑马程序员_java学习笔记12
- POJ 3686 The Windy's KM模版+拆点建图
- hadoop1.2.1编译eclipse插件
- 《高效学习OpenGL》之 操作矩阵堆栈 glPushMatrix(),glPopMatrix()
- 黑马程序员_JAVA学习笔记9
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
- 黑马程序员_JAVA学习笔记10
- python基础数据结构——列表(list), 元祖(tuple), 字典(dict), 字符串(string), 集合(set) 介绍及相互转换
- 汉诺塔(三) 栈的应用 STL
- 字典树——Immediate Decodability
- Texture Atlas Tools
- 如何在Ubuntu下安装”.deb“、”.bin“、”.tar.gz“、”.tar.bz2“格式的软件包
- UML之时序图
- Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解
- QT入门