反射学习(二) 通过反射获取成员属性
Person类代码如下:
package pojo;
public class Person {
private String name;
private int age;
public int a;
protected String b;
private String c;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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 void eat(){
System.out.println(this.name+"吃东西了");
}
public void eat(String food){
System.out.println(this.name+"吃了"+food);
}
}
1获取类的所有成员属性可以使用类对象的getfields()方法获取一个成员对象数组
//创建一个person对象
Person person=new Person();
Class cla3=person.getClass();
//通过class对象获取类的公共成员变量
Field[] fields = cla.getFields();
for (Field f:fields) {
System.out.println(f);
}
2通过getfield(String name)方法根据传入的参数名称获取类中与之类成员名称相同的属性:
//通过getfiled方法获取指定对象
Field field=cla.getField("a");
//打印a属性的信息
System.out.println(field);
//通过filed获取创建的对象中a的值
Object person_a_value = field.get(person);
//此处未给a赋值且person_a_value的值为默认值
System.out.println(person_a_value);
获取参数名称后可修改该属性的值,使用set(Object obj,Object value)方法为指定对象的指定属性值进行修改:
field.set(person,18);
为指定属性值修改后,可使用get(Object obj)方法 获取指定对象的该属性值:
System.out.print("修改后的值:");
person_a_value = field.get(person);
System.out.println(person_a_value);
执行效果如下:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上方法只可以获取公有的属性值,如果需要获取私有的属性值,需要忽略修饰符获取成员属性:
1获取所有成员变量值,不考虑权限修饰符,使用 getDeclaredFields()方法,返回一个属性对象数组:
//cla.getDeclaredFields 方法获取所有成员变量,不考虑修饰符
Field[] declaredFields = cla.getDeclaredFields();
System.out.println("----------此处为所有的成员属性----------------------------");
for (Field f:declaredFields) {
System.out.println(f);
}
2同样,忽略修饰符之后,也可以根据属性名获取指定的属性对象getDeclaredField(String name) 返回一个属性对象:
注:因为java的封装特点,直接访问私有属性违背了java 的封装特点,因此在此需要使用暴力反射的方法才能获取到私有的属性对象的值
//获取指定的成员变量
Field c = cla.getDeclaredField("c");
//忽略权限修饰符的安全检查
c.setAccessible(true);//暴力反射 否则会报错
Object c_value = c.get(person);
System.out.println("c属性的值为:"+c_value );
预先效果如下
-------------------------------------------------------------------------------------------------------------------------------------
获取成员方法对象:可以通过Class类对象调用getMethod(“方法名”)获取指定的方法对象,如方法需要传入参数,则除了传入方法名之外,还需要传入参数的类型
获取无参方法:
//获取对象的方法
Method eat=null;
try {
eat = cla.getMethod("eat");
} catch (NoSuchMethodException e) {
System.out.println("没有找到方法");
}
try {
eat.invoke(person);
} catch (InvocationTargetException e) {
System.out.println("调用方法失败");
}
获取方法后可通过方法对象调用invoke()方法执行指定的方法对象,调用incoke方法时需要传入执行方法对应的实例对象
获取带有参数的方法对象:
Method eat2=null;
try {
eat2=cla.getMethod("eat",String.class);
} catch (NoSuchMethodException e) {
System.out.println("没有找到方法");
}
try {
eat2.invoke(person,"烤冷面");
} catch (InvocationTargetException e) {
System.out.println("调用方法失败");
}
最终执行的效果如图所示: