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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© IT_JM 中级黑马   /  2013-10-12 23:19  /  1118 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Method
1、概述:Method类代表某个类中的一个成员方法。调用某个对象身上的方法,要先得到方法,再针对某个对象调用。
2、专家模式:谁调用这个数据,就是谁在调用它的专家。
如人关门:
        调用者:是门调用关的动作,对象是门,因为门知道如何执行关的动作,通过门轴之类的细节实现。
        指挥者:是人在指挥门做关的动作,只是给门发出了关的信号,让门执行。
        总结:变量使用方法,是方法本身知道如何实现执行的过程,也就是“方法对象”调用方法,才执行了方法的每个细节的。
3、方法
        Method[] getMethods();//只获取公共和父类中的方法。
        Method[] getDeclaredMethods();//获取本类中包含私有。
        Method   getMethod("方法名",参数.class(如果是空参可以写null));
        Object invoke(Object obj ,参数);//调用方法
        如果方法是静态,invoke方法中的对象参数可以为null。
如:
获取某个类中的某个方法:(如String str =”abc”)
        1)通常方式:str.charAt(1)
        2)反射方式:
                                  Method charAtMethod =Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
                                  charAtMethod.invoke(str,1);
说明:如果传递给Method对象的invoke()方法的第一个参数为null,说明Method对象对应的是一个静态方法
4、用反射方式执行某个main方法:
        首先要明确为何要用反射:在写源程序时,并不知道使用者传入的类名是什么,但是虽然传入的类名不知道,而知道的是这个类中的方法有main这个方法。所以可以通过反射的方式,通过使用者传入的类名(可定义字符串型变量作为传入类名的入口,通过这个变量代表类名),内部通过传入的类名获取其main方法,然后执行相应的内容。
此时会出现下面的问题:
        启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:
                   mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
                   mainMethod.invoke(null,(Object)new String[]{"xxx"});
        这两种方式编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了。
示例一
  1. 1. package cn.itheima;
  2. 2. //定义一个测试类
  3. 3. class Test{
  4. 4. public static void main(String[] args){
  5. 5. for(String arg : args){
  6. 6. System.out.println(arg);
  7. 7. }
  8. 8. }
  9. 9. }
  10. 10. //用反射方式根据用户提供的类名,去执行该类中的main方法。
  11. 11. import java.lang.reflect.Method;
  12. 12.
  13. 13. public class PerformedMain{
  14. 14.
  15. 15. public static void main(String[] args) throws Exception {
  16. 16. //普通方式
  17. 17. Test.main(new String[]{"123","456","789"});
  18. 18. System.out.println("-----------------------------");
  19. 19.
  20. 20. //反射方式
  21. 21. String className=args[0];
  22. 22. Class clazz=Class.forName(className);
  23. 23.
  24. 24. Method methodMain=clazz.getMethod("main",String[].class);
  25. 25. //方式一:强制转换为超类Object,不用拆包
  26. 26. methodMain.invoke(null, (Object)new String[]{"123","456","789"});
  27. 27. //方式二:将数组打包,编译器拆包后就是一个String[]类型的整体
  28. 28. methodMain.invoke(null, new Object[]{new String[]{"123","456","789"}});
  29. 29. }
复制代码
示例二:
        写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
  1. 1. //接上示例
  2. 2. //获取Person类中的方法
  3. 3. public static void getPersonMethod() throws Exception{
  4. 4. //如果想要获取方法,必须先要有对象。
  5. 5. Class clazz=Class.forName("cn.itheima.Person");
  6. 6. Person p=(Person)clazz.newInstance();
  7. 7.
  8. 8. //获取所以方法
  9. 9. Method[] mes=clazz.getMethods();//只获取公共的和父类中的。
  10. 10. //mes=clazz.getDeclaredMethods();//获取本类中包含私有。
  11. 11. for(Method me:mes){
  12. 12. System.out.println(me);
  13. 13. }
  14. 14.
  15. 15. //获取单个方法
  16. 16. Method me=clazz.getMethod("toString", null);
  17. 17. Object returnVaule=me.invoke(p, null);
  18. 18. System.out.println(returnVaule);
  19. 19. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄文伯 + 1 赞一个!

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马