当一个类中的成员方法前缀使用get或set时,这个方法在java中被称之为JavaBean。对应于get与set方法下一般都会操作一个成员变量,JavaBean也可以理解为对这个有get与set方法的变量的特殊操控方式。所以JavaBean的作用仅为对象间传递数据。
JavaBean的基础原理是反射,假定有一个private的成员变量int num。对应的有getNum与setNum方法,通过反射固然可以拿到get与set方法,但过程相对要麻烦一些。使用JavaBean功能可以简单方便快捷的得到某一成员变量的get与set方法。
类PropertyDescriptor专门用于描述一个JavaBean属性。使用示例如下:
pubic class JavaBeanDemo {
public static void main(String[] args) throws Exception {
//构造一个实例对象
Rect rect = new Rect(20, 40);
//建立一个对相应实例类内指定成员变量有关的JavaBean描述
PropertyDescriptor pd = new PropertyDescriptor("wide", Rect.class);
//获取该成员变量的JavaBean读方法
Method getWideMethod = pd.getReadMethod();
//获取该成员变量的JavaBean写方法
Method setWideMethod = pd.getWriteMethod();
//使用反射修改JavaBean成员变量
setWideMethod.invoke(rect, 90);
//使用反射获取JavaBean成员变量
int wide = (Integer)getWideMethod.invoke(rect);
System.out.println(wide);
}
}
class Rect {
private int wide;
private int high;
public Rect(int wide, int high) {
this.wide = wide;
this.high = high;
}
public int getWide() {
return wide;
}
public void setWide(int wide) {
this.wide = wide;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
}
下面这种方法可以得到一个类的所有JavaBean方法。
BeanInfo beanInfo = Introspector.getBeanInfo(rect.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
一个类拥有几个JavaBean属性取决于有几个get与set成员方法,满足以下条件之一的都可视为拥有一个JavaBean属性。
1.以小写set打头至少拥有一个参数,返回值为void的方法。
2.以小写get打头参数这空,返回值不为void的方法。
满足以上任何一条的皆视为拥有一个JavaBean属性,可以被PropertyDescriptor对象所映射。至于方法体内是否有读写成员变量跟JavaBean没有直接关系,get与set后面跟的变量名相同的视为同一个JavaBean拥有get前缀的为读功能,set前缀的为写功能。
两个JavaBean封装函数:
参数1为拥有JavaBean属性的类实例对象,参数2为要操作的成员变量名以字符串形式表现,这里的变量名只是相对于set与get后面的方法名而言的,应该以set或get后的字段为准,参数3为要修改的新值。
使用该函数前请确保valueNameStr所指变量名必然有set与get方法,否则报IntrospectionException异常。
private static void setJavaBeanValue(Object obj, String valueNameStr, Object newValue) {
new PropertyDescriptor(valueNameStr, obj.getClass()).getWriteMethod().invoke(obj, newValue);
}
private static Object getJavaBeanValue(Object obj, String valueNameStr) {
return new PropertyDescriptor(valueNameStr, obj.getClass()).getReadMethod().invoke(obj);
}