上一遍博文 , 简单介绍java 反射的常用接口,本遍博文, 我会结合项目开发的实际例子讲解下 java反射的使用

现在有个需求, 要将一个对象转换成xml格式, 或者将一串xml转换一个对象, 这时我们循序渐进, 先从最简单的入手

一: 方案①

场景 : NBA球员信息描述, 实体类如下

package test.reflect2;import org.dom4j.Element;public class UserXMLDO {private Long id;private String name;private String password;private Double height;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Double getHeight() {return height;}public void setHeight(Double height) {this.height = height;}
}

现在要把传进来的一个userXMLDO对象转成一串xml

public static String toStringXML(UserXMLDO userXMLDO) throws Exception {StringBuffer sb = new StringBuffer();sb.append("<UserInfo>");sb.append(genNodeXmlString("id", userXMLDO.getId()));sb.append(genNodeXmlString("name", userXMLDO.getName()));sb.append(genNodeXmlString("password", userXMLDO.getPassword()));sb.append(genNodeXmlString("height", userXMLDO.getHeight()));sb.append("</UserInfo>");return sb.toString();}private static String genNodeXmlString(String nodeName, Object value) {StringBuffer sb = new StringBuffer();sb.append("<");sb.append(nodeName);sb.append(">");sb.append(value);sb.append("</");sb.append(nodeName);sb.append(">");return sb.toString();}

再提供一个方法,将xml转成userXMLDO对象

public static UserXMLDO toUserXMLDO(String xml) throws Exception {UserXMLDO  userXMLDO = new UserXMLDO();Element rootElement = DocumentXmlHelper.read(xml).getRootElement();for(Iterator<?> it = rootElement.elementIterator("id"); it.hasNext();) {Element element = (Element) it.next();userXMLDO.setId(Long.valueOf(element.getText()));}for(Iterator<?> it = rootElement.elementIterator("name"); it.hasNext();) {Element element = (Element) it.next();userXMLDO.setName(element.getText());}for(Iterator<?> it = rootElement.elementIterator("password"); it.hasNext();) {Element element = (Element) it.next();userXMLDO.setPassword(element.getText());}for(Iterator<?> it = rootElement.elementIterator("height"); it.hasNext();) {Element element = (Element) it.next();userXMLDO.setHeight(Double.valueOf(element.getText()));}return userXMLDO;}

上面的方案一,是最容易的想法做法,但此做法显得有点简单粗暴 。比如我要给球员添加一个 体重 属性, 这时你会发现, 要同时修改两个方法

toStringXML()、toUserXMLDO() 的实现

修改如下 :  private Double weight;
toStringXML() : sb.append(genNodeXmlString("weight", userXMLDO.getName()));
toUserXMLDO() :
for(Iterator<?> it = rootElement.elementIterator("weight"); it.hasNext();) { 

  Element element = (Element) it.next();   userXMLDO.setHeight(Double.valueOf(element.getText()));}

添加1个属性,改起来还是可以接受, 添加2个属性,还是可以接受的、....... 再添加100个属性呢?不能接受了吧~

二: 方案② 用反射

添加类型枚举

 1 package test.reflect2;
 2
 3 import java.util.HashMap;
 4 import java.util.Map;
 5
 6 public enum NodeEnum {
 7
 8     userName("name", String.class),
 9     password("password", String.class),
10     userId("id", Long.class),
11     height("height", Double.class),
12     ;
13
14     NodeEnum(String name, Class<?> type) {
15         this.name = name;
16         this.type = type;
17     }
18
19     public static Map<String, Class<?>> getNodeMap() {
20         Map<String, Class<?>> map = new HashMap<String, Class<?>>();
21         NodeEnum[] nodeEnums = NodeEnum.values();
22         for (NodeEnum ne : nodeEnums) {
23             map.put(ne.getName(), ne.getType());
24         }
25         return map;
26     }
27
28     private String name;
29
30     private Class<?> type;
31
32     public String getName() {
33         return name;
34     }
35
36     public void setName(String name) {
37         this.name = name;
38     }
39
40     public Class<?> getType() {
41         return type;
42     }
43
44     public void setType(Class<?> type) {
45         this.type = type;
46     }
47
48
49 }

View Code

实体类添加

  1 public class UserXMLDO {
  2
  3     private static Map<String, Class<?>> nodeEnumMap = null;
  4     static {
  5         nodeEnumMap = NodeEnum.getNodeMap();
  6     }
  7
  8     private Long id;
  9     private String name;
 10     private String password;
 11     private Double height;
 12     private Double weight;
 13
 14     public static String toStringXML(UserXMLDO userXMLDO) throws Exception {
 15         StringBuffer sb = new StringBuffer();
 16         sb.append("<UserInfo>");
 17         Iterator<Entry<String, Class<?>>> it = nodeEnumMap.entrySet().iterator();
 18         while (it.hasNext()) {
 19             Entry<String, Class<?>> entry = it.next();
 20             Object object = userXMLDO.getClass().getDeclaredField(entry.getKey()).get(userXMLDO);
 21             sb.append(genNodeXmlString(entry.getKey(), object == null ? "" : object));
 22         }
 23         sb.append("</UserInfo>");
 24         return sb.toString();
 25     }
 26
 27     public static UserXMLDO toUserXMLDO(String xml) throws Exception {
 28         UserXMLDO userXMLDO = new UserXMLDO();
 29         Element rootElement = DocumentXmlHelper.read(xml).getRootElement();
 30
 31         Iterator<?> it = rootElement.elementIterator();
 32         while (it.hasNext()) {
 33             Element e = (Element) it.next();
 34             setAttrValue(userXMLDO, e.getName(), e.getTextTrim());
 35         }
 36         return userXMLDO;
 37     }
 38
 39     private static void setAttrValue(UserXMLDO userXMLDO, String nodeName, String value) throws Exception {
 40
 41         Field f = userXMLDO.getClass().getDeclaredField(nodeName);
 42         if (nodeEnumMap.get(nodeName).getName().equals(String.class.getName())) {
 43             f.set(userXMLDO, value);
 44         } else if (nodeEnumMap.get(nodeName).getName().equals(Long.class.getName())
 45                 || nodeEnumMap.get(nodeName).getName().equals(Double.class.getName())) {
 46             f.set(userXMLDO,
 47                     nodeEnumMap.get(nodeName).getDeclaredMethod("valueOf", String.class).invoke(userXMLDO, value));
 48         } else {
 49             throw new Exception("仅支持Long, String 类型");
 50         }
 51     }
 52
 53
 54     private static String genNodeXmlString(String nodeName, Object value) {
 55         StringBuffer sb = new StringBuffer();
 56         sb.append("<");
 57         sb.append(nodeName);
 58         sb.append(">");
 59         sb.append(value);
 60         sb.append("</");
 61         sb.append(nodeName);
 62         sb.append(">");
 63         return sb.toString();
 64     }
 65
 66     public Long getId() {
 67         return id;
 68     }
 69
 70     public void setId(Long id) {
 71         this.id = id;
 72     }
 73
 74     public String getName() {
 75         return name;
 76     }
 77
 78     public void setName(String name) {
 79         this.name = name;
 80     }
 81
 82     public String getPassword() {
 83         return password;
 84     }
 85
 86     public void setPassword(String password) {
 87         this.password = password;
 88     }
 89
 90     public Double getHeight() {
 91         return height;
 92     }
 93
 94     public void setHeight(Double height) {
 95         this.height = height;
 96     }
 97
 98     public Double getWeight() {
 99         return weight;
100     }
101
102     public void setWeight(Double weight) {
103         this.weight = weight;
104     }
105 }

View Code

test :

 1 public static void main(String[] args) throws Exception {
 2         UserXMLDO userXMLDO = new UserXMLDO();
 3         userXMLDO.setId(1L);
 4         userXMLDO.setName("威少");
 5         userXMLDO.setPassword("三双无解");
 6         userXMLDO.setHeight(1.90d);
 7         userXMLDO.setWeight(85.5d);
 8
 9         String xml = UserXMLDO.toStringXML(userXMLDO);
10         System.out.println(xml);
11
12         UserXMLDO userXMLDO2 = UserXMLDO.toUserXMLDO(xml);
13         System.out.println(userXMLDO2);
14     }

View Code

方案② , 体现出了很多灵活性, 把 可变 与 不可变 code 抽取出来了, 可能这样说, 或许有点难理解, 我就针对这种做法, 举个例子...

如 : 我要球员添加一个 体重 属性, 这是你会发现, 不用去修改

toStringXML()、toUserXMLDO() 的实现

你只要在  NodeEnum 增加一个类型定义即可 :

weight("weight", Double.class),

素不素改动很小, 如果换一个新人来接手维护, 每次有新的属性需求添加, 他可以很快添加完成, 不需要去改方法的实现, 这样就相对稳定了~~很巧妙做到“以不变应万变”!!


三、总结

相信比较上述两种方案后, 你会觉得反射有时特别好用, 让代码更加健硕, 但是也要记住, 不要一味盲目, 甚至刻意去使用反射, 因为性能差是反射的一大弊端!要权衡评估下。

转载于:https://www.cnblogs.com/chenmo-xpw/p/5183320.html

java反射快速入门(二)相关推荐

  1. 速看,月薪60K的技术专家总结Java的快速入门.

    作为刚刚接触Java的小白来说,最担心的应该就是Java怎么学,都需要掌握哪些内容?今天这篇文章希望能帮助大家快速入门Java,少走弯路! 如何快速入门Java? 一.作为刚接触Java的新手,肯定要 ...

  2. Java如何快速入门?Java初学者从入门到精通必看!

            作为刚刚接触Java的小白来说,最担心的应该就是Java怎么学,都需要掌握哪些内容?今天这篇文章希望能帮助大家快速入门Java,少走弯路! 如何快速入门Java? 一.作为刚接触Jav ...

  3. JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

  4. java如何快速入门及虚拟主机能装java吗?[图]

    一.java如何快速入门? 下面是一些可能帮助您成长为Java开发人员并获得更多关于该语言的知识的技巧. java如何快速入门 正确掌握Java的基本知识 由于Java为开发人员提供了如此多的特性和选 ...

  5. java web快速入门_Web安全快速入门

    java web快速入门 Web开发人员针对CORS,CSP,HSTS和所有Web安全首字母缩写词的入门知识! (A web developer's primer on CORS, CSP, HSTS ...

  6. 大白话说Java反射:入门、使用、原理,BAT 面试官 如何面试

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...

  7. JAVA程序设计-头歌实训-------# 第一阶段 Java语言快速入门

    第一阶段 Java语言快速入门 第1关:Java程序的基本框架:Hello Java World! 任务描述 本关的任务是编写你人生中第一个Java程序,从此开启你的Java实训之旅,显示效果如下: ...

  8. Java 多线程快速入门(面试概念解答一)

    Java 多线程快速入门 什么是进程,什么是线程,什么是多线程? 创建多线程有哪些方式? 启动线程是使用调用start方法还是run方法? 获取线程对象以及名称 守护线程 使用setDaemon(tr ...

  9. java游戏开发入门(二) - 菜单

    java游戏开发入门(二) - 菜单 前言 编码 主菜单 游戏内菜单(按下ESC后出现,并会暂停游戏) 效果展示 主菜单 游戏内菜单 完整代码 完整项目 前言   上一章我们创建了一个600x600的 ...

最新文章

  1. Codeforces Gym 100523E E - Gophers SET
  2. table表头固定4种方法_4种细砂回收的方法分析
  3. pandas apply函数_Pandas学习笔记(四)
  4. Docker hello workd
  5. Spring Ioc创建对象的方式
  6. 将request.getParameterMap()转换成可操作的普通Map
  7. 商业医疗险住院报销需要什么材料?
  8. WPF/Sliverlight ScrollViewer与Panel(2)
  9. 游戏 UI 自动化测试方案 Airtest Project
  10. 选修了两门课的学生学号MySQL语句_SQL 语句:在sc表中查询至少选修了两门课的学生学号的语句...
  11. 供应链三道防线(读书笔记)1(共4)
  12. 双 JK 触发器 74LS112 逻辑功能。真值表_【数电笔记】时序逻辑电路设计举例
  13. web浏览器显示网站小图标
  14. SpringBoot多模块项目如何扫描全局mapper接口和mapper.xml文件
  15. SpringMVC 学谈 (第四章)
  16. 鸿蒙OS内核分析|解读鸿蒙源码
  17. 厦大C语言上机1381
  18. STM32片上外设时钟使能、失能和复位的区别
  19. 养生医学背景PPT模板
  20. 敲七 STL队列(c++)

热门文章

  1. electron 5.0.3版本 改动的地方
  2. c++常见并且必须记住的问题
  3. 快速排序详解+各种实现方式
  4. (原创)C++11改进我们的程序之右值引用
  5. Java写入Excel文件
  6. 从入门到精通!java可视化编程软件哪个好
  7. 随笔--互联网进化论
  8. 2019.04.09 电商25 结算功能1
  9. shutil模块、json和pickle模块
  10. Hadoop 倒排索引