轉(zhuǎn)載請(qǐng)注明作者sitinspring及出處.
對(duì)對(duì)象字段設(shè)值取值是一個(gè)繁瑣的過(guò)程,尤其當(dāng)字段多時(shí)更加如此,也許大家都寫過(guò)如下代碼:
public void savePersonalInfo(PersonalInfo info) {
Element infoElm = root.addElement("personalinfo");
// 一個(gè)蘿卜一個(gè)坑
Element nameElm = infoElm.addElement("name");
nameElm.setText(info.getName());
Element sexElm = infoElm.addElement("sex");
sexElm.setText(info.getSex());
Element mobileElm = infoElm.addElement("mobile");
mobileElm.setText(info.getMobile());
Element phoneElm = infoElm.addElement("phone");
phoneElm.setText(info.getPhone());
Element addressElm = infoElm.addElement("address");
addressElm.setText(info.getAddress());
Element emailElm = infoElm.addElement("email");
emailElm.setText(info.getEmail());
Element titleElm = infoElm.addElement("title");
titleElm.setText(info.getTitle());
Element birthdayElm = infoElm.addElement("birthday");
birthdayElm.setText(info.getBirthday());
Element homepageElm = infoElm.addElement("homepage");
homepageElm.setText(info.getHomepage());
Element qqElm = infoElm.addElement("qq");
qqElm.setText(info.getQq());
Element msnElm = infoElm.addElement("msn");
msnElm.setText(info.getMsn());


}
這是取值過(guò)程,設(shè)值過(guò)程還要把上面繁瑣的過(guò)程重復(fù)一遍,工作顯得瑣碎而沒(méi)有技術(shù)含量.
在反射的幫助下,我們可以有效的簡(jiǎn)化這個(gè)繁瑣的過(guò)程,看代碼之前我們先補(bǔ)充一點(diǎn)有關(guān)類字段的反射API:
●Field[] getDeclaredFields():返回已加載類聲明的所有成員變量的Field對(duì)象數(shù)組,不包括從父類繼承的成員變量.
●Field getDeclaredField(String name):返回已加載類聲明的所有成員變量的Field對(duì)象,不包括從父類繼承的成員變量,參數(shù)name指定成員變量的名稱.
●Field[] getFields():返回已加載類聲明的所有public型的成員變量的Field對(duì)象數(shù)組,包括從父類繼承的成員變量
●Field getField(String name):返回已加載類聲明的所有成員變量的Field對(duì)象,包括從父類繼承的成員變量,參數(shù)name指定成員變量的名稱.
例程如下,假設(shè)我們是對(duì)一個(gè)名為MemberInfo的對(duì)象進(jìn)行操作,它的代碼如下:
package com.sitinspring;
public class MemberInfo{
private String name;
private String title;
private String address;
public MemberInfo(){
}
public MemberInfo(String name,String title,String address){
this.name=name;
this.title=title;
this.address=address;
}
public String toString(){
return "Name="+name+" Title="+title+" Address="+address;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
現(xiàn)在有一個(gè)MemberPersistence類,負(fù)責(zé)將MemberInfo類實(shí)例存到XML文件及從XML文件中取出,注意看設(shè)值取值的過(guò)程:
package com.sitinspring;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 用于將MemberInfo類實(shí)例存到XML文件及從XML文件中取出
*
* @author: sitinspring(junglesong@gmail.com)
* @date: 2008-1-3
*/
public class MemberPersistence {
// XML 文件名
private final String xmlFile;
// XML 文檔對(duì)象
private Document document;
// XML 文檔根節(jié)點(diǎn)
private Element root;
/**
* 構(gòu)造函數(shù),其中實(shí)例化文檔對(duì)象和根節(jié)點(diǎn)
* @param xmlFile
*/
public MemberPersistence(String xmlFile) {
this.xmlFile = xmlFile;
File file = new File(xmlFile);
try {
// 判斷文件的存在以增強(qiáng)程序的健壯性
if (file.exists()) {
// 文件存在,直接從文件讀取文檔對(duì)象
SAXReader reader = new SAXReader();
document = reader.read(file);
root = document.getRootElement();
} else {
// 文件不存在,創(chuàng)建文檔對(duì)象
document = DocumentHelper.createDocument();
root = document.addElement("companies");// 創(chuàng)建根節(jié)點(diǎn)
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 從XML文件中提取所有Member節(jié)點(diǎn)的信息,作為鏈表返回
*
* @return
*/
public List<MemberInfo> loadFromXml() {
List<MemberInfo> retval = new ArrayList<MemberInfo>();
try {
List nodes = root.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element memberElm = (Element) it.next();
MemberInfo member = new MemberInfo();
// 取得MemberInfo類的所有定義的成員變量,注意DeclaredFields不包括繼承下來(lái)的成員變量
Field[] fields = member.getClass().getDeclaredFields();
// 設(shè)置每個(gè)成員變量的值
for (Field field : fields) {
String fieldText = memberElm.elementText(field.getName());
// 必須設(shè)置為true才可以取得成員變量的值,否則field.set(member, fieldText)一句要拋出java.lang.IllegalAccessException異常
field.setAccessible(true);
field.set(member, fieldText);
}
retval.add(member);
}
return retval;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* 將一個(gè)Member對(duì)象寫到XML文件中
*
* @param member
*/
public void writeToXml(MemberInfo member) {
try {
// 在根節(jié)點(diǎn)下增加一個(gè)member節(jié)點(diǎn)
Element memberElm = root.addElement("member");
// 取得MemberInfo類的所有定義的成員變量,注意DeclaredFields不包括繼承下來(lái)的成員變量
Field[] fields = member.getClass().getDeclaredFields();
// 取得每個(gè)成員變量的值
for (Field field : fields) {
// 在member節(jié)點(diǎn)下添加屬性節(jié)點(diǎn)
Element fieldElm = memberElm.addElement(field.getName());
// 必須設(shè)置為true才可以取得成員變量的值,否則field.get(member)一句要拋出java.lang.IllegalAccessException異常
field.setAccessible(true);
fieldElm.setText((String) field.get(member));
}
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK"); // 指定XML編碼
XMLWriter writer = new XMLWriter(new FileWriter(xmlFile), format);
writer.write(document);
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
最后測(cè)試代碼:
package com.sitinspring;
import java.util.List;
public class Main{
public static void main(String[] args){
MemberPersistence persistence=new MemberPersistence("member.xml");
// 1.寫入過(guò)程
MemberInfo andy=new MemberInfo("andy","SSE","Street A No 123");
MemberInfo bill=new MemberInfo("Bill","PM","Street B No 456");
persistence.writeToXml(andy);
persistence.writeToXml(bill);
// 2.讀出過(guò)程
List<MemberInfo> members=persistence.loadFromXml();
for(MemberInfo member:members){
System.out.println(member);
}
}
}
生成和讀出的XML文件如下:
<?xml version="1.0" encoding="GBK"?>
<companies>
<member>
<name>andy</name>
<title>SSE</title>
<address>Street A No 123</address>
</member>
<member>
<name>Bill</name>
<title>PM</title>
<address>Street B No 456</address>
</member>
</companies>
看,結(jié)果是我們想要的,設(shè)值取值也變得輕巧起來(lái),比原先一個(gè)蘿卜一個(gè)坑的方式要先進(jìn)多了.
代碼下載(請(qǐng)大家自行加入dom4j包):
http://www.tkk7.com/Files/sitinspring/MemberFieldSetgetValueSample20080103135538.rar