通过反射调用类中的指定属性方法构造器
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()方法就可以完成设置和取得属性内容的操作。
- public Field getField(String name) 返回此Class对象表示的类或接口的指定的public的Field。
- public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field。
- 在Field中:
- public Object get(Object obj) 取得指定对象obj上此Field的属性内容
- public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容
- 注:在类中属性都设置为private的前提下,在使用set()和get()方法时,首先要使用Field类中的setAccessible(true)方法将需要操作的属性设置为可以被外部访问。
- public void setAccessible(true)访问私有属性时,让这个属性可见。
代码一:
package nineteen;
@MyAnnotation(value = "rengui")
public class Person extends Creature<String> implements Comparable,MyInterface{
public String name;
private int age;
int id;
//创建类时,尽量保留一个空参的构造器。
public Person() {
super();
// System.out.println("今天天气很闷热");
}
public Person(String name) {
super();
this.name = name;
}
private Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@MyAnnotation(value = "abc123")
public void show(){
System.out.println("我是一个人!");
}
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 + "]";
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
public static void info(){
System.out.println("中国人!");
}
class Bird {//内部类
}
}
代码二:
package nineteen;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestObtain {
//(一)、调用运行时类中指定的属性
@Test
public void test1() throws Exception{
Class clazz = Person.class;
//1.获取指定的属性
//getField(String fieldName):获取运行时类中声明为public的指定属性名为fieldName的属性
Field name = clazz.getField("name");
//2.创建运行时类的对象
Person p = (Person)clazz.newInstance();
System.out.println(p);
//3.将运行时类的指定的属性赋值
name.set(p,"Jerry");
System.out.println(p);
System.out.println("%"+name.get(p));
System.out.println();
//getDeclaredField(String fieldName):获取运行时类中指定的名为fieldName的属性
Field age = clazz.getDeclaredField("age");
//setAccessible 由于属性权限修饰符的限制,为了保证可以给属性赋值,需要在操作前使得此属性可被操作。
age.setAccessible(true);
age.set(p,10);
System.out.println(p);
// Field id = clazz.getField("id");
}
//(二)调用运行时类中指定的方法
@Test
public void test2() 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);//我是一个人
System.out.println(returnVal);//null
Method m2 = clazz.getMethod("toString");
Object returnVal1 = m2.invoke(p);
System.out.println(returnVal1);//Person [name=null, age=0]
//对于运行时类中静态方法的调用
Method m3 = clazz.getMethod("info");
m3.invoke(Person.class);
//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{
String className = "nineteen.Person";
Class clazz = Class.forName(className);
Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
cons.setAccessible(true);
Person p = (Person)cons.newInstance("罗伟",20);
System.out.println(p);
}
}
韧桂 2020-01-11