反射
Java反射机制允许程序在运行时通过Reflection APIs取得任何一个已知名称的class的内部信息,包括其修饰符、父类、接口、构造方法、属性、方法等,并可于运行时改变属性值或者调用方法等,使得Java语言具备“动态性”。
内省(Introspector)
内省机制就是基于反射的基础,Java语言对Bean类属性、事件的一种缺省处理方法。
JavaBean
- 属性都是私有的;
- 有无参的public构造方法;
- 对私有属性根据需要提供 公有的getXxx方法以及setXxx方法;例如属性名称为name,则有getName方法返回属性name值,setName方法设置name值;注意方法的名称通常是get或set加上属性名称,并把属性名称的首字母大写;这些方法称为getters/setters;getters必须有返回值没有方法参数;setter值没有返回值,有方法参数;
符合这些特征的类,被称为JavaBean;
内省与放射的区别
反射可以操作各种类的属性,而内省就是基于反射来操作JavaBean的属性。
内省获得的JavaBean属性
内省中确定属性是根据 set 或 get 方法,如果只要类中有getXXX方法,或者setXXX方法,或者同时有getXXX及setXXX方法,其中getXXX方法没有方法参数,有返回值;setXXX方法没有返回值,有一个方法参数;那么内省机制就认为XXX为一个属性。
内省中主要用到的类和接口
Introspector
BeanInfo
PropertyDescriptor
用例
User类
public class User{
private long uid = 0;
private String name;
private boolean sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setUid(long uid) {
this.uid = uid;
}
public long getUid() {
return uid;
}
}
使用内省操作User对象
public static void main(String[] args) throws IntrospectionException {
//获取所要操作的JavaBean信息
//BeanInfo是接口不能直接实例化,只能通过Introspector的getBeanInfo获得实例
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
//获得JavaBean中的属性描述符,通过PropertyDescriptor可以获得属性一些信息
//属性是通过set和get方法确定的,与是否在类中定义无关,详情见文章开头
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
//获取属性名字
System.out.println(pd.getName());
//获取属性类型
System.out.println(pd.getPropertyType());
//获取get方法,如果不存在则返回null
System.out.println(pd.getReadMethod());
//获取set方法,如果不存在则返回null
System.out.println(pd.getWriteMethod());
}
}
通过内省可以很轻松的将form表单的内容填充进对象里面,比反射轻松省力多了
public void insertUser(HttpServletRequest request) {
User user = new User();
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
//需要注意参数类型匹配问题,此问题不在本文讨论范围里面
pd.getWriteMethod().invoke(user, request.getParameter(pd.getName()));
}
}