一、Javabean
1.JavaBean是一種特殊的Java類,主要用于傳遞資料資訊,這種java類中的方法主要用于通路私有的字段,且方法名符合某種命名規則。
如果要在兩個子產品之間傳遞多個資訊,可以将這些資訊封裝到一個JavaBean中,這種JavaBean的執行個體對象通常稱之為值對象(Value Object,簡稱VO)。這些資訊在類中用私有字段來存儲,如果讀取或設定這些字段的值,則需要通過一些相應的方法來通路,大家覺得這些方法的名稱叫什麼好呢?JavaBean的屬性是根據其中的setter和getter方法來确定的,而不是根據其中的成員變量。如果方法名為setId,中文意思即為設定id,至于你把它存到哪個變量上,用管嗎?如果方法名為getId,中文意思即為擷取id,至于你從哪個變量上取,用管嗎?去掉set字首,剩餘部分就是屬性名,如果剩餘部分的第二個字母是小寫的,則把剩餘部分的首字母改成小的。
- setId()的屬性名---->id
- isLast()的屬性名---->last
- setCPU的屬性名是什麼?---->CPU
- getUPS的屬性名是什麼?---->UPS
總之,一個類被當作javaBean使用時,JavaBean的屬性是根據方法名推斷出來的,它根本看不到java類内部的成員變量。
2.一個符合JavaBean特點的類可以當作普通類一樣進行使用,但把它當JavaBean用肯定需要帶來一些額外的好處,我們才會去了解和應用JavaBean!好處如下:
- 在Java EE開發中,經常要使用到JavaBean。很多環境就要求按JavaBean方式進行操作,别人都這麼用和要求這麼做,那你就沒什麼挑選的餘地!
- JDK中提供了對JavaBean進行操作的一些API,這套API就稱為内省。如果要你自己去通過getX方法來通路私有的x,怎麼做,有一定難度吧?用内省這套api操作JavaBean比用普通類的方式更友善。
二、PropertyDescriptor BeanInfo BeanUtils PropertyUtils操作javabean 見代碼所示:
import java.util.Date;
public class Person
{
private String name;
private int age;
private Date birthday=new Date();//這裡要建立對象!
public Date getBirthday()
{
return birthday;
}
public void setBirthday(Date birthday)
{
this.birthday = birthday;
}
public Person(String name, int age)
{
super();
this.name = name;
this.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;
}
@Override
public String toString()
{
return this.name+" "+this.age+" "+this.birthday;
}
}
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;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntrospectorTest
{
/**
* 各種類操作javabean
*/
public static void main(String[] args)throws Exception
{
Person p=new Person("張三",23);
String propertyName="name";
//1.以下使用PropertyDescriptor操作javabean
getProperty(p, propertyName);
Object val="張凱";
setProperty(p, propertyName, val);
//2.以下使用BeanInfo操作javabean
getPropertyByBeanInfo(p, propertyName);
//3.以下使用BeanUtils操作javabean。
BeanUtils.setProperty(p, propertyName,"李四" );
//這是屬性鍊,birthday是Date類型的,Date中有setTime(long time)方法
BeanUtils.setProperty(p, "birthday.time","11111");
System.out.println(BeanUtils.getProperty(p, "birthday.time"));
//BeanUtils操作中參數是String類型的 傳回結果也是String類型
System.out.println(BeanUtils.getProperty(p, "birthday.time").getClass().getName());
//4.PropertyUtils操作javabean
PropertyUtils.setProperty(p, "name", "lily");
PropertyUtils.setProperty(p, "age", 30);//傳入是是int
System.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());//傳回是Integer
PropertyUtils.setProperty(p, "birthday.time", 10000);
System.out.println(p);
}
public static void getPropertyByBeanInfo(Person p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
BeanInfo beanInfo=Introspector.getBeanInfo(p.getClass());
PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
//周遊數組找到指定屬性
for(PropertyDescriptor pd:pds)
{
if(pd.getName().equals(propertyName))
{
System.out.println(pd.getReadMethod().invoke(p));
break;
}
}
}
//設定屬性方法
public static void setProperty(Person p, String propertyName, Object val)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
PropertyDescriptor pd1=new PropertyDescriptor(propertyName,p.getClass());
Method methodSet=pd1.getWriteMethod();
methodSet.invoke(p, val);//調用set方法把name值設定為“張凱”
System.out.println(p);
}
//得到屬性方法
private static void getProperty(Person p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException
{
//擷取javaBean的屬性描述
PropertyDescriptor pd=new PropertyDescriptor(propertyName,p.getClass());
//得到方法
Method methodGet=pd.getReadMethod();
System.out.println(methodGet.invoke(p));//調用方法
}
}
三、其他
用struts的疊代标簽不能疊代出枚舉元素的屬性,而用jstl的疊代标簽則可以。采用BeanUtils去擷取帶有抽象方法的枚舉類的成員對象的屬性時,會出現錯誤,要自己用内省加暴力反射方式才可以擷取。主要原因是枚舉類的抽象子類不是public類型的。
public static void main(String[] args) {
// TODO Auto-generated method stub
/*System.out.println(
PropertyUtils.getProperty(Sex.NONE, "title"));*/
Object bean = Sex.NONE;
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(bean.getClass());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor property:properties)
{
if(property.getName().equals("title"))
{
Method method = property.getReadMethod();
method.setAccessible(true);
Object retVal;
try {
retVal = method.invoke(bean, null);
System.out.println(retVal);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}