1、获取可变参数的函数
      获取可变参数的函数与获取参数类型为数组类型一样。 clazz.getMethod("test", Object[].class);
   其中Object为可变参数或者数组的数据类型
   例如:
   public void test(String ... params){
      ...
   }
   则获取该可变参数的函数如下:
      Class clazz = Class.forName("com.demo003.MainThread");

Method method = clazz.getMethod("test", String[].class);

 
 
2、执行调用带有可变参数的函数

     此时,我们应该如何将多个参数值传给可变参数呢?
     method.invoke(obj , new String[]{"a" ,"b" ,"C"}) ,
     或者是
     method.invoke(mainThread, "a" ,"b" ,"c" );

     这样调用对吗?
     以上两种方式的调用会报:Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
     是不是感觉挺奇怪的?
     其实Method的invoke方法的参数也是一个可变参数,如下是invoke的定义
     
     那么当参数new String[]{"a" ,"b" ,"C"})传给invoke方法时,会自动拆分成3个参数:"a" ,"b" ,"c" ,那么invoke方法自然认为目标调用函数是带有3个形参的,
     所以invoke方法调用目标函数时,会将这3个参数传递给目标函数,而目标函数仅仅是一个可变参数而已,所以就发生参数个数不一致的问题。对于反射来说,
     是通过将数组类型对象传递给目标函数的可变参数的,即它只需要将多个参数组成一个数组,然后将这个数组传递给可变参数,然后目标函数的可变参数再自动将这个数组值自动拆分成多个参数值。
     
     那么我们应该如何传呢?
     既然知道了如果数组类型与invoke函数的参数类型(为Object)可以转换,并且为一维数组时,它会自动拆分成多个参数,导致最终参数个数不一致而出现异常。
     同时知道了反射是通过将数组对象传递给目标函数的可变参数的。那么也就以意味这个,可以将这个需要传递数组类型对象转换invoke方法不可转换拆分的对象即可。
     解决方案如下:
    1)将数据类型对象强制转换成一个Object类型对象,这样就不会进行自动拆分了
     method.invoke((Object) new String[]{"a" ,"b" ,"C"}) 
 
    2)将当前数组再包装成一个一维数组,从而达到拆分出来的是一个数组对象
     Object[]p = new Object[]{ new String[]{"a" ,"b" ,"C"} }
     method.invoke(p)
 
    可能还有其他的解决方案,只要最终达到invoke不能拆分该数组参数,或者是拆分后也只有该数组对象这个参数即可
 

通过Java发射机制调用可变参数函数的更多相关文章

  1. java 使用反射调用可变参数方法

    使用反射操作对象-调用可变参数方法 要把可变参数都当做是其对应的数组类型参数; 如 show(XX... is)作为show(XX[] is)调用; 若可变参数元素类型是引用类型: JDK内部接收到参 ...

  2. 利用可变参数模拟Printf()函数实现一个my_print()函数和调用可变参数注意的陷阱!

    可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 例如,对于函数: void test(char a ...

  3. 可变参数模拟printf()函数实现一个my_print()函数以及调用可变参数需注意的陷阱

    入栈规则 可变参数函数的实现与函数调用的栈帧结构是密切相关的.所以在我们实现可变参数之前,先得搞清楚 栈是怎样传参的. 正常情况下,C的函数参数入栈遵照__stdcall规则, 它是从右到左的,即函数 ...

  4. C语言中的可变参数函数

    C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为: int printf( const char* format, ...); 它除了有一个参数format固定以外 ...

  5. php匿名函数和可变参数函数

    php匿名函数和可变参数函数 简介 直接上代码了: <?php $test1 = function($value) { echo $value; }; $test1('HelloWorld'); ...

  6. 第39篇-Java通过JNI调用C/C++函数

    在某些情况下,Java语言需要通过调用C/C++函数来实现某些功能,因为Java有时候对这些功能显的无能为力,如想使用X86_64 的 SIMD 指令提升一下业务方法中关键代码的性能,又或者想要获取某 ...

  7. Swift开发第十篇——可变参数函数&初始化方法顺序

    本篇分为两部分: 一.Swift中的可变参数函数 二.初始化方法的顺序 一.Swift中的可变参数函数 可变参数函数指的是可以接受任意多个参数的函数,在 OC 中,拼接字符串的函数就属于可变参数函数 ...

  8. C语言中可变参数函数实现原理

    C函数调用的栈结构 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈.例如,对于函数: void fu ...

  9. C可变参数函数 实现

    转自:http://blog.csdn.net/weiwangchao_/article/details/4857567 C函数要在程序中用到以下这些宏: void va_start( va_list ...

随机推荐

  1. 全局对象Application的使用,以及如何在任何地方得到Application全局对象

    Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个application对象,用来存储系统的一些信息.通常我们是不 ...

  2. c# 播放mp3

    转载:http://www.cnblogs.com/igrl/archive/2010/03/29/1699975.html /// <summary> /// 播放MP3文件 /// & ...

  3. 一个 关于 case when的SQL

    [例]从stud_grade表中查询所有同学考试成绩情况,凡成绩为空者输出“未考”.小于60分输出“不及格”.60分至70分输出“及格”.70分至90分输出“良好”.大于或等于90分时输出“优秀”. ...

  4. spring注入之使用标签 @Autowired @Qualifier

      使用标签的缺点在于必需要有源代码(由于标签必须放在源代码上),当我们并没有程序源代码的时候.我们仅仅有使用xml进行配置. 比如我们在xml中配置某个类的属性            <bea ...

  5. java 方法传参方式: 按值调用

    程序设计语言中将参数传递给方法的几种方式: 按名调用(call by name): Algol 语言采用此方式, 已成为历史; 按值调用(call by value): 方法接收到的是调用者提供的 变 ...

  6. 笛卡尔树 POJ ——1785 Binary Search Heap Construction

    相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS   Memory Limit: 30000K Total Subm ...

  7. DB2解锁

    1.登录数据库 db2 connect to 数据库名字 user 用户名 using 密码 2.进入db2top db2top -d 数据库名 进入到如下界面:  3.按下shift+u(图中U-L ...

  8. iOS UIButton文字和图片间距随意调整

    代码地址如下:http://www.demodashi.com/demo/11606.html 前记 在开发中,我们经常会遇到这么一种情况,就是一个按钮上面有图片也有文字,但是往往设计并不是我们想要的 ...

  9. Zabbix触发器函数(取前后差值)

    获取最新值last zabbix触发器方法last用于获取item最新值或者第几个值以及某个时间的哪一个值. Last (most recent) T value is > N Last (mo ...

  10. <转 >socket穿透代理代码(C++版)

    本文转自 http://blog.csdn.net/bodybo/article/details/7274865 写代码经常会遇到socket要通过代理连接服务器的情况,代理类型通畅有三种:HTTP. ...