虽然本文旨在说明如何利用反射执行带有泛型参数的方法,但是还是先来看下这个议题的背景吧,我们的服务要接入公司里面另一个平台的一个服务,我们的服务是Java语言开发,他们的服务是PHP开发,虽然远程过程调用无关乎语言,但是在传参方面遇到了一些小问题;除此之外,还记得远程过程调用需要客户端的存根和服务器端的骨架嘛,当然这都是后话了。

      1.先来看下他们的接口地址:http://ip:port/services/AccountService.php

      2.其次是接口里面我需要的那个API方法:getAccountById

      3.最后是API需要的参数:$arrIds   // 查询的用户id数组

      以上是他们官方文档此接口的基本信息,因为不需要关心结果就没贴返回类型了,接下来开始按照他们官方文档给的demo在我的服务中调试这个接口,他们的demo中给的例子接口是那种只需要传单个值的,我换成数组类型的死活不行,无奈之下问了他们的客服人员,他们的客服发给我一个截图,截图显示参数用了两个中括号包住,例如params:[[1002]]

      首先PHP中的数组对应Java中的list,我们还是先来看下调用方式吧:

XXXProxy proxy = new XXXProxy("http://ip:port/services/AccountService.php", "UTF-8", new ExceptionPolicy());
 Class<AcctountService> clazz = AcctountService.class;
 List<Long> list=new ArrayList<>();
 list.add(1002L);
 Object result = proxy.invoke(null, clazz.getMethod("getAccountById", list.getClass()),new Object[]{list});


     上面那个代理客户端是公司内部封装的,所以就不便公开了,但他本质上是实现了InvocationHandler,通过动态代理来生成代理类,实现远程过程调用。你说的没错,我本地需要写一个一模一样名字的API接口;如下:

public interface AcctountService {
  String[] getAccountById(ArrayList<Long> arrIds);
 }

     然后通过代理客户端生成的代理类通过反射调用目标方法,由于泛型编译后有类型擦除的原因,虽然invoke方法的args参数只能是object数组类型,但是数组里面可以传任何类型的参数,我原本以为invoke里面的args参数传一个new Object[]{1002L},他也会当成只有一个元素的数组,结果理解错了,new Object[]{list}里面是需要一个list的参数的