反射使您的程序代码能够接入装载到 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 也提供了类似的功能。那么本文就作为一个了解反射的范例罢了。