java Introspector内省和Reflect反射学习、联系和区别
一、反射和内省
1、反射: 将一个类中属性、方法拆解中一个个集合。 Methods[],Fields[]。 对于任意一个类,可以通过反射获取所有的属性和方法;对于任意一个对象可以通过反射调用任意一个方法。
2、内省: java提供的一套API,用于操作某个属性的getter/setter方方法。这些属性命名必须符合java bean命名规范。 (属性名的第二个字母是小写,则转getter/setter方法时,将第一个字母变成大写! 待确定!)
3、联系: 都是通过反射的原理来操作类的相关属性和方法。
4、区别: 反射是直接操作类的各种属性;内省是在反射的基础上进行了一次封装。如:使用内省获取属性值,肯定会调用 getter方法,而反射可以直接获取到。
二、代码示例
1、 定义一个普通的java类 User
/**
* description: 定义一个普通的java类,将采用反射reflect 和内省 introspector 进行测试调用
* @version v1.0
* @author w
* @date 2018年9月4日下午10:21:20
*/
public class User extends Person {
private String name;
private int age;
// 省略 getter/setter
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
2、使用反射操作类的属性和方法
@Test
public void reflect() throws Exception{
// 1.使用反射操作类的属性和方法
User user = new User();
Field nameF = user.getClass().getDeclaredField("name");
nameF.setAccessible(true);
nameF.set(user, "小明");
Field ageF = User.class.getDeclaredField("age");
ageF.setAccessible(true);
ageF.set(user, 111);
System.out.println("姓名:"+nameF.get(user)+" -- 年龄 :"+ageF.getInt(user));
}
3、.使用内省操作类的属性和方法
@Test
public void introspector() throws Exception{
// 2.使用内省 PropertyDescriptor 操作类的属性和方法
User user = new User();
PropertyDescriptor pd = new PropertyDescriptor("name", User.class);
// 等价于调用 setName() 方法
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(user, "晓红同学");
// 等价于调用 setAge() 方法
PropertyDescriptor pd2 = new PropertyDescriptor("age", User.class);
Method writeMethod2 = pd2.getWriteMethod();
writeMethod2.invoke(user, 18);
// 等价于调用 getName() 和 getAge() 方法
Method readMethod = pd.getReadMethod();
Object name = readMethod.invoke(user);
Method readMethod2 = pd2.getReadMethod();
Object age = readMethod2.invoke(user);
System.out.println("姓名2:"+name+" --- 年龄2:"+age);
// 3.使用 Introspector 操作所有属性
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor p : propertyDescriptors) {
// 获取所有属性,包含父类属性
System.out.println(p);
// xx do something
}
MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
for (MethodDescriptor m : methodDescriptors) {
// 获取所有方法,包含父类方法
System.out.println(m.getDisplayName());
// xx do something
}
}