黑马程序员技术交流社区

标题: 用反射根据类名执行该类中的main方法 [打印本页]

作者: 柯玲    时间: 2012-7-16 22:43
标题: 用反射根据类名执行该类中的main方法
本帖最后由 柯玲 于 2012-7-18 06:35 编辑

在毕老师高新里面,有如下代码,我的疑问也相应贴在后面,希望大家能发表一下见解:
  1. import java.lang.reflect.Method;
  2. public class TakeMain{
  3.         public static void main(String[] args) throws Exception{
  4.                 String startClassName=args[0];//不明白为什么要将数组的第一个元素假设成要加载的类的名字,为什么要这样假设?是怎么想到用这样的假设呢?
  5.                 Method method=Class.forName(startClassName).getMethod("main", String[].class);
  6.                 method.invoke(null, (Object)new String[]{"aa","bb","cc"});//这里我试过只有强转的方式才可以,new Object()的方式报告编译错误,又是什么原因造成?
  7.         }
  8. }
  9. class TestMain {
  10.         public static void main(String[] args) {
  11.                 for(String arg:args){
  12.                         System.out.println(arg);
  13.                 }
  14.         }
  15. }
复制代码

作者: 王飞    时间: 2012-7-16 23:17
String[] args 这是运行时你给主函数传入的参数,主函数会根据你传入的这个参数反射获取相应的类信息



import java.lang.reflect.Method;
public class aa{
        public static void main(String[] args) throws Exception{
                String startClassName=args[0];//不明白为什么要将数组的第一个元素假设成要加载的类的名字,为什么要这样假设?是怎么想到用这样的假设呢?
                因为这是用到了反射,你不知道你要反射的是那个类,所以以参数的形式传入,只需在运行时传入这个参数--既类名,那么就可以获取这个类中的所以信息,然后操作
                其二:类名可以通过读取配置文件获取,你程序N年前就已经写好了,那么你现在想用这个程序就只需写一个N年后的类, 把配置文件中的类名改成你写的类名,那么程序就会运行你写的这个类
                这样就不必去改源代码,-----------这是反射的重点哦哦哦

                Method method=Class.forName(startClassName).getMethod("main", String[].class);
                method.invoke(null, (Object)new String[]{"aa","bb","cc"});//这里我试过只有强转的方式才可以,new Object()的方式报告编译错误,又是什么原因造成?
---报错的原因应该是:人家接受的是数组,而你直接传入的是new Object对象进去当然会错了额

                这个张老师的视频里面有提到:第二个参数有两种形式写法
                第一就是你写的那种
                第二就是:因为jdk的新特性,会对String[]进行拆包,你可以在拆包前在给他加一层包,当拆完包后就可以用String[]了

               
        }
}
class TestMain {
        public static void main(String[] args) {
                for(String arg:args){
                        System.out.println(arg);
                }
        }
}
作者: 王飞    时间: 2012-7-17 00:56
王飞 发表于 2012-7-16 23:17
String[] args 这是运行时你给主函数传入的参数,主函数会根据你传入的这个参数反射获取相应的类信息

你这里:  Method method=Class.forName(startClassName).getMethod("main", String[].class);
的 String[].class接收的是一个数组

而你这里--new Object(new String[]{"aa","bb","cc"}    传入 String[].class的是一个Object对象,
当然错了啊 :)


楼主明白否????

作者: 王飞    时间: 2012-7-17 01:00
王飞 发表于 2012-7-16 23:17
String[] args 这是运行时你给主函数传入的参数,主函数会根据你传入的这个参数反射获取相应的类信息

虽然你
new Object(new String[]{"aa","bb","cc"})
new了一个对象,对象里面装的是数组对象,
但是编译器编译的时候需要的是一个数组对象而不是一个里面装了一个数组的对象
作者: 柯玲    时间: 2012-7-17 01:25
王飞 发表于 2012-7-17 01:00
虽然你
new Object(new String[]{"aa","bb","cc"})
new了一个对象,对象里面装的是数组对象,

LS错了,PPT上写的有两种方法,一种将数组强转成Object,一种是因为JDK1.4拆包,所以要把数组包装一个对象,让它拆出来的东西依然是数组,但是我在把数组作为元素装入Object对象的时候,编译器报错了,不支持这种写法,我想有可能的原因是目前机器上JDK的兼容性问题,用的是1.7版本
作者: 黄昆    时间: 2012-7-17 01:56
package cn.itcast.day01;

import java.lang.reflect.Method;



public class TakeMain{

        public static void main(String[] args) throws Exception{

                String startClassName=args[0];

                Method method=Class.forName(startClassName).getMethod("main", String[].class);

                method.invoke(null, new Object[]{new String[]{"aa","bb","cc"}});   //不对呀,我怎么能编译通过呀?你是不是忘记设Program arguments的值呀?

        }

}

class TestMain {

        public static void main(String[] args) {

                for(String arg:args){

                        System.out.println(arg);

                }

        }

}
   

QQ截图20120717014459.png (24.81 KB, 下载次数: 51)

QQ截图20120717014459.png

作者: 柯玲    时间: 2012-7-17 07:41
王飞 发表于 2012-7-17 01:00
虽然你
new Object(new String[]{"aa","bb","cc"})
new了一个对象,对象里面装的是数组对象,

对不起,是我错了,我那样做确实是只传进去一个包含数组的对象,而不是一个数组,谢谢提醒




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2