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. package cn.itheima;
- 2. //定义一个测试类
- 3. class Test{
- 4. public static void main(String[] args){
- 5. for(String arg : args){
- 6. System.out.println(arg);
- 7. }
- 8. }
- 9. }
- 10. //用反射方式根据用户提供的类名,去执行该类中的main方法。
- 11. import java.lang.reflect.Method;
- 12.
- 13. public class PerformedMain{
- 14.
- 15. public static void main(String[] args) throws Exception {
- 16. //普通方式
- 17. Test.main(new String[]{"123","456","789"});
- 18. System.out.println("-----------------------------");
- 19.
- 20. //反射方式
- 21. String className=args[0];
- 22. Class clazz=Class.forName(className);
- 23.
- 24. Method methodMain=clazz.getMethod("main",String[].class);
- 25. //方式一:强制转换为超类Object,不用拆包
- 26. methodMain.invoke(null, (Object)new String[]{"123","456","789"});
- 27. //方式二:将数组打包,编译器拆包后就是一个String[]类型的整体
- 28. methodMain.invoke(null, new Object[]{new String[]{"123","456","789"}});
- 29. }
复制代码示例二: 写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
- 1. //接上示例
- 2. //获取Person类中的方法
- 3. public static void getPersonMethod() throws Exception{
- 4. //如果想要获取方法,必须先要有对象。
- 5. Class clazz=Class.forName("cn.itheima.Person");
- 6. Person p=(Person)clazz.newInstance();
- 7.
- 8. //获取所以方法
- 9. Method[] mes=clazz.getMethods();//只获取公共的和父类中的。
- 10. //mes=clazz.getDeclaredMethods();//获取本类中包含私有。
- 11. for(Method me:mes){
- 12. System.out.println(me);
- 13. }
- 14.
- 15. //获取单个方法
- 16. Method me=clazz.getMethod("toString", null);
- 17. Object returnVaule=me.invoke(p, null);
- 18. System.out.println(returnVaule);
- 19. }
复制代码
|