您的位置:首页 > 大数据 > 人工智能

关于反射带有数组参数的方法的调用(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}} ,不让编译器优化,这就是网上通常说的两种方案了

嘿嘿。。大家如果感觉说的好的话,要多来访问一下喔。。。。……^_^
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐