最近在研究Java的动态代理时对InvocationHandler中invoke方法中的第一个参数一直不理解它的用处,某度搜索也搜不出结果,最后终于在stackoverflow上找到了答案。

这是原文的链接:http://stackoverflow.com/questions/22930195/understanding-proxy-arguments-of-the-invoke-method-of-java-lang-reflect-invoca

原文对这个参数的解释是:

1. 可以使用反射获取代理对象的信息(也就是proxy.getClass().getName())。

2. 可以将代理对象返回以进行连续调用,这就是proxy存在的目的。因为this并不是代理对象,

下面看源代码

接口:

  1. private interface Account {
  2. public Account deposit (double value);
  3. public double getBalance ();
  4. }

Handler:

  1. private class ExampleInvocationHandler implements InvocationHandler {
  2. private double balance;
  3. @Override
  4. public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
  5. // simplified method checks, would need to check the parameter count and types too
  6. if ("deposit".equals(method.getName())) {
  7. Double value = (Double) args[0];
  8. System.out.println("deposit: " + value);
  9. balance += value;
  10. return proxy; // here we use the proxy to return 'this'
  11. }
  12. if ("getBalance".equals(method.getName())) {
  13. return balance;
  14. }
  15. return null;
  16. }
  17. }

使用:

  1. Account account = (Account) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {Account.class, Serializable.class},
  2. new ExampleInvocationHandler());
  3. // method chaining for the win!
  4. account.deposit(5000).deposit(4000).deposit(-2500);
  5. System.out.println("Balance: " + account.getBalance());

我们看到如果返回proxy的话可以对该代理对象进行连续调用

那为什么不返回this,而是返回proxy对象呢?

因为this对象的类型是ExampleInvocationHandler,而不是代理类$Proxy0

除此之外,不返回代理对象的话,还能返回其他信息,如balance。

InvocationHandler中invoke方法中的第一个参数proxy的用途的更多相关文章

  1. InvocationHandler中invoke()方法的调用问题

    转InvocationHandler中invoke()方法的调用问题 Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandl ...

  2. ASP.NET中HttpApplication中ProcessRequest方法中运行的事件顺序;ASP.NET WebForm和MVC总体请求流程图

    ASP.NET中HttpApplication中ProcessRequest方法中运行的事件顺序 1.BeginRequest  開始处理请求 2.AuthenticateRequest 授权验证请求 ...

  3. 【mybatis】service层中一个方法中使用mybatis进行数据库的 多个修改操作,可能是update也可能是delete操作,但是sql语句命名执行并且在控制台打印出来了,但是数据库中未更新到数据【事务的问题】

    问题描述: service层中一个方法中使用mybatis进行数据库的 多个修改操作,可能是update也可能是delete操作,但是sql语句命名执行并且在控制台打印出来了,但是数据库中未更新到数据 ...

  4. js中的方法如何传入多个参数

    js中的方法如何传入多个参数 $(function () { let parameter1 = 1; let parameter2 = 'Hello World'; let parameter3 = ...

  5. Proxy是在什么时候调用InvocationHandler的invoke方法的

    最近看到spring的动态代理,扒到深处看到时 Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);看到这一句,顿时比较懵逼,还是 ...

  6. EXT经验--在调试中通过查看handler的第一个参数的xtype得知该参数信息及该handler的归属

    EXT模拟了OPP的思想,因此很多问题可以像JAVA语音那样去思考它.在实际阅读EXT时,常常需要我们搞清楚某个函数.某个对象的归属.如某个参数变量.方法属于哪个类,如下: 这是我今天在群中发出的问题 ...

  7. Objective-C中一个方法如何传递多个参数的理解

    原来如此 Objective-C语法中多参数传递方法经常是初学者最容易犯困的地方.我自己也是刚刚悟出来与大家分享. 分析 由于我们已有的语言经验告诉我们定义方法都是: 一个类型匹配一个参数(动态语言甚 ...

  8. PHP中CURL方法curl_setopt()函数的一些参数 (转)

    bool curl_setopt (int ch, string option, mixed value) curl_setopt()函数将为一个CURL会话设置选项.option参数是你想要的设置, ...

  9. 解决webkit浏览器中js方法中使用window.event提示未定义的问题

    这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...

随机推荐

  1. python 虚拟环境操作 virtualenv +virtualenvwrapper

    Window 下创建python的虚拟环境 下载工具 pip install virtualenv 创建虚拟环境目录 # 注意此命令创建的虚拟环境目录是在当前目录下 virtualenv testen ...

  2. 使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存

    使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存 今天要介绍的是Simple-Spring-Memcached,它封装了对MemCached的调用,使MemCa ...

  3. Spring ApplicationContext(十)finishRefresh

    ApplicationContext(十)finishRefresh Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 经过 ...

  4. js、css、img等浏览器缓存问题的2种解决方案

    转:http://www.jb51.net/article/42339.htm 浏览器缓存的意义在于提高了执行效率,但是也随之而来带来了一些问题,导致服务端修改了js.css,客户端不能更新,下面有几 ...

  5. 利用PHP脚本辅助MySQL数据库管理2-表主键表索引

    <?php $dbi = new DbMysql; $dbi->dbh = 'mysql://root:mysql@127.0.0.1/coffeetest'; $map = array( ...

  6. Reduce 和 Transduce 的含义

    一.reduce 的用法 reduce是一种数组运算,通常用于将数组的所有成员"累积"为一个值. var arr = [1, 2, 3, 4]; var sum = (a, b) ...

  7. SVN基本操作 (zz)

    SVN基本操作 分类: LINUX 原文地址:SVN基本操作 作者:tuyer 文章摘要:SVN 基本操作:SVN是什么 Svn是一个离线的代码管理,可以多个人一起修改,然后再将修改的内容提交到Svn ...

  8. Python 单列

    1.__new__内置方法 在对类进行实例化时自动执行 功能1:为对象分配空间 功能2:返回空间的引用 2.单列实现方法 class MusicPlayer: # 记录对象内存引用,初始值为None ...

  9. jQuery Autocomplete 备忘录

    之前使用过此 widget,如今再次需要,发现很多东西已经记不起来了,当然之前用的版本也不一样. 使用之前当然是先认真阅读官方的说明文档和示例,这点很重要,而不是东一块西一点的去网上瞎找资料.Opti ...

  10. 使用django发送邮件(smtp)

    首先在 seeting 最下面+上 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_USE_TLS = False ...