Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 258|回复: 0

[Java反射学习]使用反射简化对象成员的设值取值

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-30 23:58:03 | 显示全部楼层 |阅读模式
    对对象字段设值取值是一个繁琐的过程,尤其当字段多时更加如此,也许大家都写过如下代码:


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

    现在有一个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文件如下:


      
       
      <?
      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
      >
      

      

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






    源码下载:http://file.javaxxz.com/2014/10/30/235802156.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-6 00:25 , Processed in 0.365371 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表