春风博客

春天里,百花香...

导航

<2008年1月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

统计

公告

MAIL: junglesong@gmail.com
MSN: junglesong_5@hotmail.com

Locations of visitors to this page

常用链接

留言簿(11)

随笔分类(224)

随笔档案(126)

个人软件下载

我的其它博客

我的邻居们

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

使用反射简化繁琐的对对象成员设值取值的过程续

本文是“使用反射简化繁琐的对对象成员设值取值的过程”的续文。

在前文的例子中,类MemberInfo的成员变量都是String类型,如果说其中有其它类型int,boolean等,如果变成下面的类:
public class Member{
    
private String name;
    
private String title;    
    
private int age;
    
private boolean isMale;
}

这样以前的给字段设置值的方法就不好用了,如之奈何?

其实只要肯想,办法是有的,反射的getField不好用了,我们还有getMethod,胡屠户死了,咱们也不吃带毛的猪。通过反射的getMethod方法,咱们可以得到类中定义的函数,再对类的getter、setter函数动动手脚就能达到我们的目的。

请看代码,特别是带注释的动了手脚的函数部分。
新定义的Member类:
package com.sitinspring;

public class Member{
    
private String name;
    
private String title;    
    
private int age;
    
private boolean isMale;
    
    
public Member(){
    }

    
    
public Member(String name,String title,int age,boolean isMale){
        
this.name=name;
        
this.title=title;
        
this.age=age;
        
this.isMale=isMale;
    }

    
    
/**
     * 额外增加的从整数类型年龄得到为字符状态年龄的函数
     * 
@return
     
*/

    
public String getAge() {
        
return String.valueOf(age);
    }

    
    
/**
     * 额外增加的将字符状态年龄转化为整数类型年龄的函数
     * 
@param age
     
*/

    
public void setAge(String age) {
        
this.age = Integer.valueOf(age);
    }

    
    
/**
     * 额外增加的取得字符类型性别的函数
     * 
@return
     
*/

    
public String getIsMale() {
        
return isMale?"":"";
    }

    
    
/**
     * 额外增加的将字符类型性别转化为布尔类型性别的函数
     * 
@param strMale
     
*/

    
public void setIsMale(String strMale) {
        
this.isMale = strMale.equals("");
    }

    
    
/**
     * 改写的函数,将生成的getAge变成了getIntAge
     * 
@return
     
*/

    
public int getIntAge() {
        
return age;
    }
    
    
    
public String toString(){
        
return "Name="+name+" Title="+title+" Age="+age+" 性别="+getIsMale();
    }


    
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;
    }


    
public void setAge(int age) {
        
this.age = age;
    }


    
public boolean isMale() {
        
return isMale;
    }


    
public void setMale(boolean isMale) {
        
this.isMale = isMale;
    }

}

上面四个函数就是为了方便反射而写的,再看MemberPersistence的代码:
package com.sitinspring;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
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;

/**
 * 用于将Member类实例存到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<Member> loadFromXml() {
        List
<Member> retval = new ArrayList<Member>();

        
try {
            List nodes 
= root.elements("member");

            
for (Iterator it = nodes.iterator(); it.hasNext();) {
                Element memberElm 
= (Element) it.next();

                Member member 
= new Member();

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

                
// 设置每个成员变量的值
                for (Field field : fields) {
                    String fieldText 
= memberElm.elementText(field.getName());

                    
// 通过反射取得setter函数(通过getSetMethodName函数得出,参数为成员名),其参数为String
                    Method method = member.getClass().getMethod(
                            getSetMethodName(field.getName()),
                            
new Class[] { String.class });

                    
// 通过反射调用setter函数给成员变量赋值
                    method.invoke(member, new Object[] { fieldText });
                }


                retval.add(member);
            }


            
return retval;
        }
 catch (Exception ex) {
            ex.printStackTrace();
        }


        
return null;
    }


    
/**
     * 将一个Member对象写到XML文件中
     * 
     * 
@param member
     
*/

    
public void writeToXml(Member 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());

                
// 通过反射取得getter函数(通过getGetMethodName函数得出,参数为成员名),其参数无
                Method method = member.getClass().getMethod(
                        getGetMethodName(field.getName()), 
new Class[] {});

                
// 通过反射调用getter函数给取得成员变量的值
                Object result = method.invoke(member, new Object[] {});

                
// 将此值赋给节点文字
                fieldElm.setText((String) result);
            }


            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();
        }

    }


    
/**
     * 取得“getter”函數的函數名
     * 
     * 
@param field
     * 
@return
     
*/

    
private static String getGetMethodName(String field) {
        
return "get" + field.substring(01).toUpperCase() + field.substring(1);
    }


    
/**
     * 取得“setter”函數的函數名
     * 
     * 
@param field
     * 
@return
     
*/

    
private static String getSetMethodName(String field) {
        
return "set" + field.substring(01).toUpperCase() + field.substring(1);
    }

}


最后的调用处还是和上篇差不多:
package com.sitinspring;

import java.util.List;

public class Main{
    
public static void main(String[] args){        
        MemberPersistence persistence
=new MemberPersistence("member.xml");
        
        
// 1.写入过程
        Member andy=new Member("Andy","SSE",25,true);
        Member bill
=new Member("Bill","PM",26,false);    
        persistence.writeToXml(andy);
        persistence.writeToXml(bill);
        
        
// 2.读出过程
        List<Member> members=persistence.loadFromXml();
        
for(Member member:members){
            System.out.println(member);
        }

    }

}

生成的文件:
<?xml version="1.0" encoding="GBK"?>

<companies>
  
<member>
    
<name>Andy</name>
    
<title>SSE</title>
    
<age>25</age>
    
<isMale></isMale>
  
</member>
  
<member>
    
<name>Bill</name>
    
<title>PM</title>
    
<age>26</age>
    
<isMale></isMale>
  
</member>
</companies>

代码下载(请自行加入dom4j包):
http://www.blogjava.net/Files/sitinspring/MemberMethodSetgetValueSample20080105151118.rar

posted on 2008-01-05 15:10 sitinspring 阅读(2296) 评论(3)  编辑  收藏 所属分类: Java基础

评论

# re: 使用反射简化繁琐的对对象成员设值取值的过程续 2008-01-06 04:39 thinkbase

需要吗? xstream 不是就可以了么  回复  更多评论   

# re: 使用反射简化繁琐的对对象成员设值取值的过程续 2008-01-06 11:17 qiyadeng

对的, xstream,可以帮你完成。  回复  更多评论   

# re: 使用反射简化繁琐的对对象成员设值取值的过程续 2008-01-06 14:16 Jeff Lau

BeanUtils类也可以实现这样类似的功能啊  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
sitinspring(http://www.blogjava.net)原创,转载请注明出处.