博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小白学习Java反射之代理(实际代码例子)
阅读量:3897 次
发布时间:2019-05-23

本文共 3743 字,大约阅读时间需要 12 分钟。

此篇博客参考自:

首先是讲这段代码的流程,以大明星刘德华为例,把代理当作他的“经纪人”

在这里插入图片描述
首先是person类:

package com.Kit.proxy;public interface Person {
//他又要唱歌和跳舞两种情况 String sing(String name); String dance(String name);}

LiuDeHua类:

package com.Kit.proxy;//这个明星继承了person这个接口,并且实现对应的方法public class LiuDeHua implements  Person{
public String sing(String name) {
System.out.println("刘德华唱"+name+"这首歌"); return "歌唱完了,谢谢大家"; } public String dance(String name) {
System.out.println("刘德华跳"+name+"这支舞"); return "舞跳完了,谢谢大家"; }}

LiuDeHuaProxy类:

package com.Kit.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//所以在这个例子当做,代理就相当于是经纪人的形式出现的public class LiuDeHuaProxy {
//设计一个类变量记住代理类要代理的目标对象 //所以为什么不能直接 private一个 Liuedehua呢 //private LiuDeHua ldh=new LiuDeHua(); private Person ldh=new LiuDeHua(); //再设计一个方法生成代理对象 public Person getProxy(){
//使用Proxy.newProxyInstance(ClassLoader loader, Class
[] interfaces, InvocationHandler h)返回某个对象的代理对象 //这次参数都是通过反射来获取到的 // newProxyInstance方法用来返回一个代理对象, // 这个方法总共有3个参数,ClassLoader loader用来指明生成代理对象使用哪个类装载器, // Class
[] interfaces用来指明生成哪个对象的代理对象, // 通过接口指定,InvocationHandler h // 用来指明产生的这个代理对象要做什么事情。所以我们只需要调用newProxyInstance方法就可以得到某一个对象的代理对象了 return (Person) Proxy.newProxyInstance(LiuDeHuaProxy.class.getClassLoader(), ldh.getClass().getInterfaces(), new InvocationHandler() {
//这个接口就是已定义了invoke这个方法,而new InvocationHandler就是针对这个接口的一个匿名实现类 //invoke有三个参数,proxy是把代理对象之间传递进来,method就是把代理对象当前调用的方法传递过来,args就是把方法参数传递过来 //代理还是反射的作用吧 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//这边如果是调用的是代理对象的sing的话 if(method.getName().equals("sing")){
System.out.println("我是他的经纪人,唱歌需要花十万"); //收完钱之后,就可以进行对应的操作了,对应的参数就是对应的代理对象和对应的名字 //这边比较好奇的,居然是ldh,也就是之前创建好的对象 return method.invoke(ldh,args); } if(method.getName().equals("dance")){
System.out.println("我是他的经纪人,跳舞需要花二十万"); //交完钱之后就可以调用了 return method.invoke(ldh,args); } //这个是我自己改的,也不知道对不对 return "别的活他不接"; } }); }}

最后的ProxyTest测试类:

package com.Kit.proxy;public class ProxyTest {
public static void main(String[] args) {
//首先创建一个代理,也就相当于是经纪人 LiuDeHuaProxy proxy=new LiuDeHuaProxy(); //然后通过代理获得一个对象,因为那边是person,所以这里也需要是person Person liuDeHua= proxy.getProxy(); //用来做对比 // LiuDeHua liuDeHua1=new LiuDeHua(); //那就是对应的操作了,这里就会发现,你调用直接的dance的时候,是会需要经过一个proxy的,可以和其他的对比一下 // liuDeHua.dance("yyy"); // System.out.println("**********"); //下面就是可以直接跳舞 // liuDeHua1.dance("yyy"); // System.out.println("**********"); //还有一个细节就是,把之前的代码换成下面这种 String result=liuDeHua.sing("xxx"); System.out.println(result); //就会发现 先是代理的出现,再是ldh的出现,最后才是 ldh的return }}

就此例子讲一下代理这个机制,也就是我自己的粗略理解:

重点就是看看这个代理的代码:
首先是创建了一个 对应的Person类:

private Person ldh=new LiuDeHua();

因为是私有的,所以需要有一个公共方法来调用他:

也就是 public Person getProxy()
这个方法就是返回了一个Person 类实例(这个实例由反射机制调用new出来的)
所以就需要重点说一下这个方法:
Proxy.newProxyInstance
这个方法的参数分别是:
1.ClassLoader loader 指定的类装载器
2.Class[] interfaces 一组接口
3.InvocationHandler h 调用处理器生成动态实例

所以需要好好了解这几个参数存在的意义

对于第一个参数,其实差不多可以不用管他,知道用类名.class.getClassLoader()
第二个参数,是指定这个对象实现需要什么接口,并且一般来说就是一个接口就行了, 也就是对象.getClass().getInterfaces()
第三个参数,是最重要的,称之为调用处理器,在这里也就是调用invoke方法,所以有需要在里面把这个invoke方法进行编写:这里就很玄虚了,这几个参数是什么:
Object proxy ,Method method ,Object[] args:
在这里插入图片描述
这个解释就很秒。

转载地址:http://zsfen.baihongyu.com/

你可能感兴趣的文章
Windows环境下Android NDK环境搭建
查看>>
NDK Build 用法(NDK Build)
查看>>
Android NDK开发起步Hello Jni
查看>>
[已解决]AutoCompleteTextView 不显示匹配的内容,因为将空的内容添加进去了
查看>>
object c的浅拷贝(地址拷贝)和深拷贝(对象拷贝)
查看>>
object c son字符串的解析
查看>>
object c 非常强大的类的属性复制kcv键值码赋值
查看>>
Java中普通代码块,构造代码块,静态代码块区别及代码示例
查看>>
iOS 第4课 UILabel
查看>>
[已解决]junit.framework.AssertionFailedError: No tests found in
查看>>
“服务器端跳转”和“客户端跳转”的区别
查看>>
Datatables基本初始化——jQuery表格插件
查看>>
Servlet监听器——实现在线登录人数统计小例子
查看>>
Oracle笔记——简单查询语句 Oracle入门
查看>>
基于Hibernate和Struts2的用户管理系统小案例
查看>>
打开.class文件的方法
查看>>
基于windows平台Git+GitHub+Hexo搭建个人博客(一)
查看>>
基于windows平台Git+GitHub+Hexo搭建个人博客(二)
查看>>
Windows平台下SVN安装配置及使用
查看>>
python简便的编辑工具:jupyter notebook
查看>>