关于反射带有数组参数的方法的调用(main)
2012-03-18 10:02
447 查看
首先说一下什么叫糖衣语法
引入这种语法和原来的语法并没有什么区别,这种语法的引入只是方便程序员的使用,而它是在
在编译阶段又转换成原来的语法
在JDK1.5以后有许多这种例子,如是高级for ,枚举,泛型,自动装箱拆箱等,这些都是JDK引入的糖衣语法,当家还有
一个可变参数
举个例子,大家写一个可变参数的方法,用反编译工作查看编译后的class 文件
public statc void show(int ...a)
{
for(int i:a)
System.out.println(i);
}
在主函数里面调用 show(1,2,3)
在查看反编译后的class 文件为
public static void alter(int[] a) {
int[] arrayOfInt;
int j = (arrayOfInt = a).length; for (int i = 0; i < j; ++i) { int i = arrayOfInt[i];
System.out.println(i); }
}
主函数则为 show(int []{1,2,3})
这家这下明白了什么是糖衣语法吧,其实就是编译器的一种优化
好了,我们说一下数组参数类型的方法的反射
我们得到了 Method m = Test.class.getMethod("main",String[].class)
这个没问题,我们确实得到了main 方法的对象m
下面我们要做的就是执行,执行的方法是 m.invoke(????),这个里面的参数貌似不是太好写。。。。
我们先 说一下invoke 方法的参数类型 invoke(Object,Object...obj) ,前面一个参数是绑定我们要执行的对象,静态方法null ,没什么问题
我们看第二个参数,是一个 Object ...obj 可变参数
一般如果没猜错的话,大家传入就是 m.invoke(null,new String[]{"aaa","bbb"}) ,嘿嘿。其实我也是这样想滴。。。。。
大家来分析一下哈。你传入了一个new String[{"aaa","bbb"}),这是一个数组,有一点要说明一下,如果你给可变参数的 方法传了多个参数,在编译后会自动创建一个数组将它们放在一起作为参数,如上面的show(new int[]{1,2,3}) 而如果你传入了直接是一个数组的话,那么这将不会进行任何优化,直接将数组传进行,如果show(int a[]{1,2,3}) ,它将直接还是show(int a[]{1,2,3})
下面我们还是说上面的那个问题。其实现在已经很简单了。既然我们传进去的是一个new String[]{"aaa","bbbb"} 其实它传过去的还是new String[]{"aaa","bbbb"} ,并没有任何改变,大家会想正好啊,main 方法的参数正好也是一个数组,怎么会不可以,大家想一想,JDK1.4以前没有可变参数,invoke使用是一个数组,为什么要使用数组呢?
哈哈。。很简单,因为我们的参数的个数不确定,所以,在invoke 执行时,会把 数组中的每个元素都作为一个反射方法的一个参数,那么在执行到main 方法时,它执行的
会是什么样子呢。当然很简单,就是main("aaa","bbb") ,这下大家知道为什么会错了吧。
知道原因后修改应该很简单的了吧。就是直接将参数作为一个值,而不作为数组,这样在编译器优化后就成了一个new Object[]{new String[]{1,2,3}},这样main 方法就会成功得到了 String[] 数组,当然,大家也可以直接传进去 new Object[]{new String[]{1,2,3}} ,不让编译器优化,这就是网上通常说的两种方案了
嘿嘿。。大家如果感觉说的好的话,要多来访问一下喔。。。。……^_^
引入这种语法和原来的语法并没有什么区别,这种语法的引入只是方便程序员的使用,而它是在
在编译阶段又转换成原来的语法
在JDK1.5以后有许多这种例子,如是高级for ,枚举,泛型,自动装箱拆箱等,这些都是JDK引入的糖衣语法,当家还有
一个可变参数
举个例子,大家写一个可变参数的方法,用反编译工作查看编译后的class 文件
public statc void show(int ...a)
{
for(int i:a)
System.out.println(i);
}
在主函数里面调用 show(1,2,3)
在查看反编译后的class 文件为
public static void alter(int[] a) {
int[] arrayOfInt;
int j = (arrayOfInt = a).length; for (int i = 0; i < j; ++i) { int i = arrayOfInt[i];
System.out.println(i); }
}
主函数则为 show(int []{1,2,3})
这家这下明白了什么是糖衣语法吧,其实就是编译器的一种优化
好了,我们说一下数组参数类型的方法的反射
我们得到了 Method m = Test.class.getMethod("main",String[].class)
这个没问题,我们确实得到了main 方法的对象m
下面我们要做的就是执行,执行的方法是 m.invoke(????),这个里面的参数貌似不是太好写。。。。
我们先 说一下invoke 方法的参数类型 invoke(Object,Object...obj) ,前面一个参数是绑定我们要执行的对象,静态方法null ,没什么问题
我们看第二个参数,是一个 Object ...obj 可变参数
一般如果没猜错的话,大家传入就是 m.invoke(null,new String[]{"aaa","bbb"}) ,嘿嘿。其实我也是这样想滴。。。。。
大家来分析一下哈。你传入了一个new String[{"aaa","bbb"}),这是一个数组,有一点要说明一下,如果你给可变参数的 方法传了多个参数,在编译后会自动创建一个数组将它们放在一起作为参数,如上面的show(new int[]{1,2,3}) 而如果你传入了直接是一个数组的话,那么这将不会进行任何优化,直接将数组传进行,如果show(int a[]{1,2,3}) ,它将直接还是show(int a[]{1,2,3})
下面我们还是说上面的那个问题。其实现在已经很简单了。既然我们传进去的是一个new String[]{"aaa","bbbb"} 其实它传过去的还是new String[]{"aaa","bbbb"} ,并没有任何改变,大家会想正好啊,main 方法的参数正好也是一个数组,怎么会不可以,大家想一想,JDK1.4以前没有可变参数,invoke使用是一个数组,为什么要使用数组呢?
哈哈。。很简单,因为我们的参数的个数不确定,所以,在invoke 执行时,会把 数组中的每个元素都作为一个反射方法的一个参数,那么在执行到main 方法时,它执行的
会是什么样子呢。当然很简单,就是main("aaa","bbb") ,这下大家知道为什么会错了吧。
知道原因后修改应该很简单的了吧。就是直接将参数作为一个值,而不作为数组,这样在编译器优化后就成了一个new Object[]{new String[]{1,2,3}},这样main 方法就会成功得到了 String[] 数组,当然,大家也可以直接传进去 new Object[]{new String[]{1,2,3}} ,不让编译器优化,这就是网上通常说的两种方案了
嘿嘿。。大家如果感觉说的好的话,要多来访问一下喔。。。。……^_^
相关文章推荐
- 黑马程序员—反射调用main方法的问题总结(涉及可变参数)(反射参数是一个数组的函数要小心)
- 关于java的反射,调用私有方法(有参数私有方法),私有属性
- Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用
- Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用
- 如何通过反射调用带有ref或者out的参数的方法[迁移]
- 黑马程序员—反射调用main方法的问题总结(涉及可变参数)
- C#如何通过反射调用带有ref或者out的参数的方法
- 有数组参数的方法的反射调用
- 使用JAVA的反射机制反射带有数组参数的私有方法
- 使用JAVA的反射机制反射带有数组参数的私有方法
- 反射方法调用时的一个错误:参数计数不匹配( parameter count mismatch )
- Atitit.通过null 参数 反射 动态反推方法调用
- 黑马程序员-反射调用其他类main方法
- c++中关于数组作为函数参数并传递数组元素个数的几种有效方法的讨论
- * java 中的数组 对象数组 以及main方法中的参数 x y不用中间参数实现交换
- Java 反射调用带基本数据类型参数的方法
- 关于main方法中的args的参数
- 首页文章分类 关于 Search private(私有)方法单元测试无法覆盖?那就用反射调用来测试private(私有)方法
- c# 调用带有参数的存储过程方法--oracle篇
- C#中反射调用带out参数的方法