JAVA中反射机制三
反射三 利用反射获取对象的方法,并调用方法
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上面;因此在遇到数组参数传递的时候需要注意。

浙公网安备 33010602011771号