---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、JavaBean类概述
1、JavaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有 的字段,且方法名符合某种规则。
2、如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要相应的方法来访问,如getter方法和setter方法。
3、JavaBean的属性是根据其中的getter方法和setter方法来确定的,而不是根据其中的成员变量。举个例子,如果某个JavaBean类有方法setId()与getId(),那么我们认为它有个叫做id的属性,至于它内部实际封装的私有成员变量叫什么则不必关心。
4、根据方法名推断属性名的规则:
1)去掉set/get前缀,剩余部分就是属性名。2)若剩余部分的第二个字母为小写,则将剩余部分的首字母改为小写;若其为大写,则剩余部分的首字母仍为大写。举例,
setId()的属性名:id;
isLast()的属性名:last;
setCPU的属性名:CPU;
5、一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当作JavaBean类使用会带来一些额外好处:
1)java EE开发中,经常会使用到JavaBean类。很多环境要求按JavaBean方式进行操作,别人都这么用和要求这么做,我们也别无选择。
2)JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。使用内省操作JavaBean比使用普通类的方式更加方便。
二、内省
1、内省的概念
内省,英文名introspector,意思是自省、反省。它主要用于对JavaBean类进行操作。
2、通过内省对JavaBean进行操作
例1:简单的操作方式
package com.cn.itcast;
public class ReflectPoint {
private int x;
private int y;
public ReflectPoint(int x,int y){
super();
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
package com.cn.itcast;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IntrospectorTest {
public static void main(String[] args) throws Exception{
ReflectPoint rp=new ReflectPoint(3, 5);
String propertyName="x";
//通过普通反射方式获取属性x的值时,需要经历下面几个步骤,十分繁琐
//"x"-->"X"-->"getX"-->methodGetX-->x
//通过内省,获取x属性的值
PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());//通过属性名,获取该对象rp下该属性x的属性描述器
Method methodGetX=pd.getReadMethod();//通过属性描述器,获取该属性x的读方法,即getter方法
Object retVal=methodGetX.invoke(rp);//利用反射调用该getter方法,获取属性x的值
System.out.println(retVal);
//通过内省,设置x属性的值
Method methodSetX=pd.getWriteMethod();//通过属性描述器,获取该属性x的写方法,即setter方法
methodSetX.invoke(rp, 7);////利用反射调用该setter方法,设置属性x的值
System.out.println(rp.getX());
}
}
输出结果:
3
7
利用重构,将例1中的代码进行简化:
public class IntrospectorTest {
public static void main(String[] args) throws Exception{
ReflectPoint rp=new ReflectPoint(3, 5);
String propertyName="x";
Object retVal = getProperty(propertyName, rp);
System.out.println(retVal);
Object value=7;
setProperty(propertyName, rp, value);
System.out.println(rp.getX());
}
private static void setProperty(String propertyName, Object rp,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());
Method methodSetX=pd.getWriteMethod();
methodSetX.invoke(rp, value);
}
private static Object getProperty(String propertyName, Object rp)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());
Method methodGetX=pd.getReadMethod();
Object retVal=methodGetX.invoke(rp);
return retVal;
}
}
例2:较麻烦的操作方式
public class IntrospectorTest {
public static void main(String[] args) throws Exception{
ReflectPoint rp=new ReflectPoint(3, 5);
String propertyName="x";
//较麻烦的操作方式
BeanInfo beanInfo=Introspector.getBeanInfo(rp.getClass()); //获取该JavaBean类的beanInfo,它存储了该JavaBean的所有属性信息
PropertyDescriptor[] pds= beanInfo.getPropertyDescriptors();//获取该JavaBean类的所有属性描述器
Object retVal=null;
for(PropertyDescriptor pd:pds){
if(pd.getName().equals(propertyName)){ //判断是否x属性的描述器
Method methodGetX=pd.getReadMethod();
retVal=methodGetX.invoke(rp);
break;
}
}
System.out.println(retVal);//3
}
}
3、Beanutils工具包
Beanutils工具包是阿帕奇公司提供的开源工具包,用于更方便地操作JavaBean类。
例3:
package com.cn.itcast;
public class ReflectPoint {
private Date birthday=new Date();
private int x;
private int y;
public ReflectPoint(int x,int y){
super();
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
package com.cn.itcast;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntrospectorTest {
public static void main(String[] args) throws Exception{
ReflectPoint rp=new ReflectPoint(3, 5);
String propertyName="x";
//利用Beanutils工具包操作JavaBean类
System.out.println(BeanUtils.getProperty(rp, propertyName));//直接获取某个对象的某个属性的值,类似例1中重构后的方法
BeanUtils.setProperty(rp, propertyName,"9");//直接设置某个对象的某个属性的值,类似例1中重构后的方法,但注意其接收的值类型为Object,常用String类型,更符合开发实际需求
System.out.println(rp.getX());
System.out.println(BeanUtils.getProperty(rp, propertyName).getClass().getName());//说明该方法返回值为String类型,比例1中重构后的方法更符合开发实际需求
//支持对属性链的连续调用
BeanUtils.setProperty(rp, "birthday.time", "111");
System.out.println(BeanUtils.getProperty(rp, "birthday.time"));
//get方法返回该属性本来的类型,set方法只接受该属性本类的类型
PropertyUtils.setProperty(rp, propertyName, 12);
System.out.println(rp.getX());
}
}
输出结果:
3
9
java.lang.String
111
12