JAVA中反射机制三
声明:如需转载请说明地址来源:http://www.cnblogs.com/pony1223
反射三 利用反射获取对象的方法,并调用方法
1.利用反射获取对象的方法,我们仍然利用上面的Person类,然后在里面建立方法,方法我们知道有无参方法,有参方法,私有方法,静态方法,如下所示:
package study.reflect; import java.io.InputStream; import java.util.List; public class Person { /** * 为了测试用 */ public String name = "test"; public Person() { } public Person(String name) { System.out.println("name:"+name); } public Person(String name,int age) { System.out.println("name:"+name+",age:"+age); } private Person(List list) { System.out.println("list"); } public void sayHello() { System.out.println("hello"); } public void sayHello(String name) { System.out.println("hello,"+name); } public String sayHello(String name,int age) { System.out.println("hello,"+name+",age:"+age); return name; } private void sayHello(InputStream in) { System.out.println("inputStream"); } public static void sayHello(Person person) { System.out.println(person); } }
2.通过反射我们要获取方法,并执行方法,代码如下:
package study.reflect; import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Method; import org.junit.Test; /** * 解析类,并调用方法 * @author Pony * */ public class Demo03 { @Test public void test01() throws Exception { Class<?> clazz = Class.forName("study.reflect.Person"); Person person = (Person) clazz.newInstance(); Method method = clazz.getMethod("sayHello", null); method.invoke(person, null); } @Test public void test02() throws Exception { Class<?> clazz = Class.forName("study.reflect.Person"); Person person = (Person) clazz.newInstance(); Method method = clazz.getMethod("sayHello", String.class); method.invoke(person, "world"); } @Test public void test03() throws Exception { Class<?> clazz = Class.forName("study.reflect.Person"); Person person = (Person) clazz.newInstance(); Method method = clazz.getMethod("sayHello", String.class,int.class); method.invoke(person, "world",12); } @Test public void test04() throws Exception { Class<?> clazz = Class.forName("study.reflect.Person"); Person person = (Person) clazz.newInstance(); Method method = clazz.getMethod("sayHello",Person.class); method.invoke(person,person); } @Test public void test05() throws Exception { Class<?> clazz = Class.forName("study.reflect.Person"); Person person = (Person) clazz.newInstance(); Method method = clazz.getDeclaredMethod("sayHello",InputStream.class); method.setAccessible(true); method.invoke(person,new FileInputStream("D:\\1.txt")); } }
3.特殊main方法如何调用:
如果person 中有如下的方法: public static void main(String[] args) { System.out.println("main"); } 如果向下面方式: @Test public void test06() throws Exception { Class<?> clazz = Class.forName("study.reflect.Person"); //Person person = (Person) clazz.newInstance(); Method method = clazz.getMethod("main",String[].class); //静态方法,所以可以直接传空 method.invoke(null,new String[]{"1","2"}); } 会出现一个下面的错误: java.lang.IllegalArgumentException: wrong number of arguments at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at
产生错误的原因为,在JDK1.4的时候是没有可变参数的因此,传入的是Object[] 数组的方式,那么JDK 拿到数组后就会拆分,这个时候new String[]{“1”,”2”},就会拆分成了两个String类型的参数,那么这个时候去Pesron 中,发现没有两个均为String类型的方法main,这个时候就会出现了上面的额参数个数不匹配,解决的方法为:
method.invoke(null,new String[]{"1","2"});
改成:
method.invoke(null,new Object[]{new String[]{"1","2"}});
这样拆完后,里面就一个参数了,对应到我们要的main上面;因此在遇到数组参数传递的时候需要注意。