A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© yp324 中级黑马   /  2013-6-5 14:28  /  1706 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class InvokeMain
{
         public static void main(String[] args) throws Exception
         {
                 String str = args[0];//args[0]的值是Main类的类名

                 Method methodMain = Class.forName(str).getMethod("main", String[].class);
                 //methodMain.invoke(null, new String[]{"jeek", "wong"});错误!!!!!
                methodMain.invoke(null, new Object[]{new String[]{"jeek", "wong"}});//正确
                //methodMain.invoke(null, (Object)new String[]{"jeek", "wong"});正确
         }
}

class Main
{
         public static void main(String[] args)
         {
                 for(String arg : args)
                 {
                         System.out.println(arg);
                 }
         }
}
上面实现的是通过反射方式调用调用一个类的main方法
invoke方法的第二个参数是可变参数,public Object invoke(Object obj,Object... args)
传入的可变参数可以看做是一个数组传入.为啥直接传入 new String[]{"jeek", "wong"} 会运行出错.???!!!!

下面也是一个可变参数的问题定义了一个字符串数组         String[] a = new String[]{"ab", "bc", "cd"};使用Arrays这个数组工具类中asList方法.asList的定义是public static <T> List<T> asList(T... a) 也是接收可变参数...执行语句System.out.println(Arrays.asList(a));结果正确.......
上面的两段代码中都使用了可变参数.(Object... obj).传入String[] 就不同了..为什么第一个挂了..两者有什么区别吗???

评分

参与人数 1技术分 +1 收起 理由
曹睿翔 + 1 很给力!

查看全部评分

3 个回复

倒序浏览
本帖最后由 刘正祥 于 2013-6-5 16:57 编辑

invokeObject obj, Object... args) 这个可变参数是对象类型的
如果该值为基本类型,则应首先适当地将其包装在对象中,如果该值的类型为一组基本类型,则数组元素不被包装在对象中,
但是String并不是基本类型,所以应该把它转为对象

回复 使用道具 举报
在jdk1.5之前,也就是没有出现重载的可变参数特性之前,invoke(Object obj, Object... args),多参数是通过一个Object数组传递进去的,也就是invoke(Object obj, Object[] args).

在楼主的例子中main方法接收的参数是String[] args这个数组。在执行代码methodMain.invoke(null, new String[]{"jeek", "wong"});时,我们的本意是将new String[]{"jeek", "wong"}作为一个Object参数传递给invoke方法,如果按照jdk1.5,执行方法invoke(Object obj, Object... args),这显然是符合规范的,貌似我们这样做是没有错的,这是为什么会编译出错,并且提示:参数的个数不对。

我们不难想到编译器实际上把new String[]{"jeek", "wong"}解析成了一个Object的数组,所以导致了参数不一致的情况,这又是为什么呢?查询文档可知,在实际编译过程中,编译器会根据参数类型选择性的调用invoke(Object obj, Object... args)或者jdk1.5之前定义的方法invoke(Object obj, Object[] args)。这样就不难理解为什么编译器把new String[]{"jeek", "wong"}解析成了一个Object数组,因为它选择使用了invoke(Object obj, Object[] args)方法。

为了解决这个问题,我们可以将其转型为Object类型,即(Object)new String[]{"jeek", "wong"}或者显式地将其保存在一个Object数组中new Object[]{new String[]{"jeek", "wong"}}。这样就避免了歧义的发生。

希望我的回答能够帮助到楼主。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马