Java通过反射调用类中的指定方法、指定属性、指定构造器

Java通过反射调用类中的指定方法、指定属性、指定构造器

1.调用指定方法

通过反射,调用类中的方法,通过Method类完成。步骤:

  1. 通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
  2. 之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

Object invoke(Object obj, Object … args),说明

  1. Object 对应原方法的返回值,若原方法无返回值,此时返回null
  2. 若原方法若为静态方法,此时形参Object obj可为null
  3. 若原方法形参列表为空,则Object[] args为null
  4. 若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。

2. 调用指定属性

在反射机制中,可以直接通过Field类操作类中的属性,通过Field类提供的set()和get()方法就可以完成设置和取得属性内容的操作。

  1. public Field getField(String name) 返回此Class对象表示的类或接口的指定的public的Field。
  2. public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field。
  • 在Field中:
  1. public Object get(Object obj) 取得指定对象obj上此Field的属性内容
  2. public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容

3. 调用指定构造器

在反射机制中,可以通过获取运行时类的构造器的方法,并指定构造器属性,来指定构造器;

  1. public Constructor getConstructor(Class … parameterTypes):获取声明为public的指定构造器
  2. public Constructor getDeclaredConstructor(Class … parameterTypes):获取运行时类中声明的指定的构造器

注:在类中属性都设置为private的前提下,在使用set()和get()方法时,首先要使用Field类中的setAccessible(true)方法将需要操作的属性设置为可以被外部访问。
public void setAccessible(true)访问私有属性时,让这个属性可见。

	//调用运行时类中指定的方法
	@Test
	public void test3() throws Exception {
		Class clazz = Person.class;
		//getMethod(String methodName,Class ... params):获取运行时类声明为public的方法
		Method m1 = clazz.getMethod("show");
		Person p  = (Person)clazz.newInstance();
		//调用指定的方法:Object invoke(Object obj,Object ... obj)
		Object returnVal = m1.invoke(p);//I am person
		System.out.println(returnVal);//null
		
		Method m2 = clazz.getMethod("toString");
		Object returnVal2 = m2.invoke(p);
		System.out.println(returnVal2);//Person [name=null, age=0]
		//对于静态方法的调用
		Method m3 = clazz.getMethod("info");
		m3.invoke(Person.class);//Chinese
		
		//getDeclaredMethod(String methodName,Class ... params):获取运行时类中声明的指定的方法
		Method m4 = clazz.getDeclaredMethod("display",String.class,Integer.class);
		m4.setAccessible(true);//私有方法需要注意权限
		Object value = m4.invoke(p, "CHN",10);//我的国籍是:CHN
		System.out.println(value);//10
	}
	//调用运行时类中指定的属性
	@Test
	public void test3() throws Exception {
		Class clazz  = Person.class;
		//1.获取指定的属性
		//getField(String name):获取运行时类声明为public的指定属性名为fieldName的属性
		Field name = clazz.getField("name");
		//2.创建运行时类的对象
		Person p = (Person)clazz.newInstance();
		System.out.println(p);//Person [name=null, age=0]
		//3.将运行类指定的属性赋值
		name.set(p, "Jerry");
		System.out.println(p);//Person [name=Jerry, age=0]
		
		System.out.println();
		//getDeclaredField(Strin fieldName):获取运行时类中指定的的名为:fieldName的属性
		Field age = clazz.getDeclaredField("age");
		//由于属性权限修饰符的限制,为了保证可以给属性赋值,需要在操作前使得属性可以被操作
		age.setAccessible(true);//设置为可访问的
		age.set(p, 10);
		System.out.println(p);//Person [name=Jerry, age=10]
		
//		Field id = clazz.getField("id");
	}
	//获取指定的构造器,创建运行时类的对象
	@Test
	public void test3() throws Exception {
		String className = "testReflection.Person";
		Class clazz = Class.forName(className);
		
		Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
		cons.setAccessible(true);
		Person p = (Person)cons.newInstance("Jhon",20);
		System.out.println(p);//Person [name=Jhon, age=20]
	}
@MyAnnotation("person")
public class Person extends Creature<String> implements Comparable<Object>,MyInterface {
	public String name;
	private int age;
	int id;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	...
	@MyAnnotation(value = "abc")
	public void show() {
		System.out.println("I am a person");
	}
	private Integer display(String nation,Integer i) throws Exception{
		System.out.println("我的国籍是:"+ nation);
		return i;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(Object o) {
		return 0;
	}
	
	public static void info() {
		System.out.println("Chinese");
	}
	
	class Bird{
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值