启天论坛软件硬件技术Java技术 → 使用反射简化对象成员的设值取值


  共有469人关注过本帖树形打印

主题:使用反射简化对象成员的设值取值

帅哥哟,离线,有人找我吗?
junsan
  1楼 个性首页 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 总掌门
等级:管理员 帖子:11920 积分:10843 威望:757 精华:24 注册:2005-7-14 15:13:00
使用反射简化对象成员的设值取值  发帖心情 Post By:2008-10-11 1:42:00



对对象字段设值取值是一个繁琐的过程,尤其当字段多时更加如此,也许大家都写过如下代码:
public void savePersonalInfo(PersonalInfo info) {
        Element infoElm = root.addElement("personalinfo");
        
        // 一个萝卜一个坑
        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());
.....................
}
这是取值过程,设值过程还要把上面繁琐的过程重复一遍,工作显得琐碎而没有技术含量.

在反射的帮助下,我们可以有效的简化这个繁琐的过程,看代码之前我们先补充一点有关类字段的反射API:
●Field[] getDeclaredFields():返回已加载类声明的所有成员变量的Field对象数组,不包括从父类继承的成员变量.
●Field getDeclaredField(String name):返回已加载类声明的所有成员变量的Field对象,不包括从父类继承的成员变量,参数name指定成员变量的名称.
●Field[] getFields():返回已加载类声明的所有public型的成员变量的Field对象数组,包括从父类继承的成员变量
●Field getField(String name):返回已加载类声明的所有成员变量的Field对象,包括从父类继承的成员变量,参数name指定成员变量的名称.

例程如下,假设我们是对一个名为MemberInfo的对象进行操作,它的代码如下:
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;
    }
}


主页:http://www.rsky.com.cn

培训论坛:http://www.javastar.org

Blog:http://blog.csdn.net/junnef

技术交流QQ:334620162

培训咨询QQ:66883074

合租咨询QQ:631066985

MSN:junsanjin@hotmail.com

Emial:junsanjin@263.net

传真:(010)950507转747393
启天合组-专业合租空间提供商 支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
junsan
  2楼 个性首页 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 总掌门
等级:管理员 帖子:11920 积分:10843 威望:757 精华:24 注册:2005-7-14 15:13:00
  发帖心情 Post By:2008-10-11 1:43:00

现在有一个MemberPersistence类,负责将MemberInfo类实例存到XML文件及从XML文件中取出,注意看设值取值的过程:
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类实例存到XML文件及从XML文件中取出
 * 
 * @author: sitinspring(junglesong@gmail.com)
 * @date: 2008-1-3
 */
public class MemberPersistence {
    // XML 文件名
    private final String xmlFile;

    // XML 文档对象
    private Document document;

    // XML 文档根节点
    private Element root;

    /**
     * 构造函数,其中实例化文档对象和根节点
     * @param xmlFile
     */
    public MemberPersistence(String xmlFile) {
        this.xmlFile = xmlFile;

        File file = new File(xmlFile);

        try {
            // 判断文件的存在以增强程序的健壮性
            if (file.exists()) {
                // 文件存在,直接从文件读取文档对象
                SAXReader reader = new SAXReader();
                document = reader.read(file);
                root = document.getRootElement();
            } else {
                // 文件不存在,创建文档对象
                document = DocumentHelper.createDocument();
                root = document.addElement("companies");// 创建根节点
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 从XML文件中提取所有Member节点的信息,作为链表返回
     * 
     * @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不包括继承下来的成员变量
                Field[] fields = member.getClass().getDeclaredFields();

                // 设置每个成员变量的值
                for (Field field : fields) {
                    String fieldText = memberElm.elementText(field.getName());
                    // 必须设置为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;
    }

    /**
     * 将一个Member对象写到XML文件中
     * 
     * @param member
     */
    public void writeToXml(MemberInfo member) {
        try {
            // 在根节点下增加一个member节点
            Element memberElm = root.addElement("member");

            // 取得MemberInfo类的所有定义的成员变量,注意DeclaredFields不包括继承下来的成员变量
            Field[] fields = member.getClass().getDeclaredFields();

            // 取得每个成员变量的值
            for (Field field : fields) {
                // 在member节点下添加属性节点
                Element fieldElm = memberElm.addElement(field.getName());
                // 必须设置为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();
        }
    }
}
最后测试代码:
package com.sitinspring;

import java.util.List;

public class Main{
    public static void main(String[] args){        
        MemberPersistence persistence=new MemberPersistence("member.xml");
        
        // 1.写入过程
        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.读出过程
        List<MemberInfo> members=persistence.loadFromXml();
        for(MemberInfo member:members){
            System.out.println(member);
        }
    }
}生成和读出的XML文件如下:
Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><?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>

看,结果是我们想要的,设值取值也变得轻巧起来,比原先一个萝卜一个坑的方式要好多了.

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:testpoi.zip



主页:http://www.rsky.com.cn

培训论坛:http://www.javastar.org

Blog:http://blog.csdn.net/junnef

技术交流QQ:334620162

培训咨询QQ:66883074

合租咨询QQ:631066985

MSN:junsanjin@hotmail.com

Emial:junsanjin@263.net

传真:(010)950507转747393
启天合组-10人 15人 20人 多人合租空间 支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
junsan
  3楼 个性首页 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 总掌门
等级:管理员 帖子:11920 积分:10843 威望:757 精华:24 注册:2005-7-14 15:13:00
  发帖心情 Post By:2008-10-11 1:47:00

文章中代码不完整,请下载附件


主页:http://www.rsky.com.cn

培训论坛:http://www.javastar.org

Blog:http://blog.csdn.net/junnef

技术交流QQ:334620162

培训咨询QQ:66883074

合租咨询QQ:631066985

MSN:junsanjin@hotmail.com

Emial:junsanjin@263.net

传真:(010)950507转747393
启天合组-专业合租空间提供商 支持(0中立(0反对(0回到顶部