反射使您的程序代码能够接入装载到 JVM 中的类的内部信息,允许你编写与执行时,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。
首先观察下面的 XML 文件:
<?xml version = '1.0' encoding = 'gb2312'?>
<ROOT>
<ARSUBITEM num="1">
<C_ITEMNO>300200500009</C_ITEMNO>
<C_ITEMNAME>20050112测试</C_ITEMNAME>
<C_SUBITEMNO>200543030000010</C_SUBITEMNO>
<C_SUBITEMNAME>20010112标段2</C_SUBITEMNAME>
<C_FUNCNAME>监督备案</C_FUNCNAME>
</ARSUBITEM>
</ROOT>
该 XML 文件描述了一个标段当前流程信息,接下来把它翻译成 VO :
public class BidProcess implements Serializable{
private String itemNo;
private String itemName;
private String subItemNo;
private String subItemName;
private String functionName;
/**
* @return 返回 functionName。
*/
public String getFunctionName() {
return functionName;
}
/**
* @param functionName 要设置的 functionName。
*/
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
/**
* @return 返回 itemName。
*/
public String getItemName() {
return itemName;
}
/**
* @param itemName 要设置的 itemName。
*/
public void setItemName(String itemName) {
this.itemName = itemName;
}
/**
* @return 返回 itemNo。
*/
public String getItemNo() {
return itemNo;
}
/**
* @param itemNo 要设置的 itemNo。
*/
public void setItemNo(String itemNo) {
this.itemNo = itemNo;
}
/**
* @return 返回 subItemName。
*/
public String getSubItemName() {
return subItemName;
}
/**
* @param subItemName 要设置的 subItemName。
*/
public void setSubItemName(String subItemName) {
this.subItemName = subItemName;
}
/**
* @return 返回 subItemNo。
*/
public String getSubItemNo() {
return subItemNo;
}
/**
* @param subItemNo 要设置的 subItemNo。
*/
public void setSubItemNo(String subItemNo) {
this.subItemNo = subItemNo;
}
}
从 XML 构造 VO ,放入 List 中,代码如下:
public class VOFactory {
// 构造出的对象集合
private ArrayList list=new ArrayList();
/** 利用反射获取结果集 */
public List parse(Serializable source, String xml){
try{
//构造 XML 输入流
ByteArrayInputStream ba=new ByteArrayInputStream(xml.getBytes());
//Dom4J 初始化
SAXReader reader = new SAXReader();
Document document = reader.read(ba);
Element root = document.getRootElement();
//获得类对象
Class c = source.getClass();
//获得构造函数
Constructor[] cons=c.getDeclaredConstructors();
Constructor con=cons[0];
//获得类中的字段
Field[] fields = c.getDeclaredFields();
//设置访问private字段的权限
AccessibleObject.setAccessible(fields,true);
//以特定名称获得 XML 元素列表
List lis = root.elements("ARSUBITEM");
//"ARSUBITEM"元素下的子元素
for(int i=0;i<lis.size();i++){
Element element=(Element)lis.get(i);
Iterator iter=element.elementIterator();
//从构造函数实例化对象
Serializable localObj=(Serializable)con.newInstance(null);
//按照字段个数循环
int j=0;
while(iter.hasNext()){
Element e=(Element)iter.next();
fields[j].set(localObj,e.getText());
j++;
}
list.add(localObj);
}
}catch(Exception e){
e.printStackTrace();
}
return list;
}
}
通过对以上代码原形进行修改,可实现分页、结果集嵌套等需求。在写作本文时,我偶然发现了 Jakarta Commons BeanUtils 也提供了类似的功能。那么本文就作为一个了解反射的范例罢了。