java反射快速入门(二)
上一遍博文 , 简单介绍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反射快速入门(二)相关推荐
- 速看,月薪60K的技术专家总结Java的快速入门.
作为刚刚接触Java的小白来说,最担心的应该就是Java怎么学,都需要掌握哪些内容?今天这篇文章希望能帮助大家快速入门Java,少走弯路! 如何快速入门Java? 一.作为刚接触Java的新手,肯定要 ...
- Java如何快速入门?Java初学者从入门到精通必看!
作为刚刚接触Java的小白来说,最担心的应该就是Java怎么学,都需要掌握哪些内容?今天这篇文章希望能帮助大家快速入门Java,少走弯路! 如何快速入门Java? 一.作为刚接触Jav ...
- JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...
接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...
- java如何快速入门及虚拟主机能装java吗?[图]
一.java如何快速入门? 下面是一些可能帮助您成长为Java开发人员并获得更多关于该语言的知识的技巧. java如何快速入门 正确掌握Java的基本知识 由于Java为开发人员提供了如此多的特性和选 ...
- java web快速入门_Web安全快速入门
java web快速入门 Web开发人员针对CORS,CSP,HSTS和所有Web安全首字母缩写词的入门知识! (A web developer's primer on CORS, CSP, HSTS ...
- 大白话说Java反射:入门、使用、原理,BAT 面试官 如何面试
写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...
- JAVA程序设计-头歌实训-------# 第一阶段 Java语言快速入门
第一阶段 Java语言快速入门 第1关:Java程序的基本框架:Hello Java World! 任务描述 本关的任务是编写你人生中第一个Java程序,从此开启你的Java实训之旅,显示效果如下: ...
- Java 多线程快速入门(面试概念解答一)
Java 多线程快速入门 什么是进程,什么是线程,什么是多线程? 创建多线程有哪些方式? 启动线程是使用调用start方法还是run方法? 获取线程对象以及名称 守护线程 使用setDaemon(tr ...
- java游戏开发入门(二) - 菜单
java游戏开发入门(二) - 菜单 前言 编码 主菜单 游戏内菜单(按下ESC后出现,并会暂停游戏) 效果展示 主菜单 游戏内菜单 完整代码 完整项目 前言 上一章我们创建了一个600x600的 ...
最新文章
- Codeforces Gym 100523E E - Gophers SET
- table表头固定4种方法_4种细砂回收的方法分析
- pandas apply函数_Pandas学习笔记(四)
- Docker hello workd
- Spring Ioc创建对象的方式
- 将request.getParameterMap()转换成可操作的普通Map
- 商业医疗险住院报销需要什么材料?
- WPF/Sliverlight ScrollViewer与Panel(2)
- 游戏 UI 自动化测试方案 Airtest Project
- 选修了两门课的学生学号MySQL语句_SQL 语句:在sc表中查询至少选修了两门课的学生学号的语句...
- 供应链三道防线(读书笔记)1(共4)
- 双 JK 触发器 74LS112 逻辑功能。真值表_【数电笔记】时序逻辑电路设计举例
- web浏览器显示网站小图标
- SpringBoot多模块项目如何扫描全局mapper接口和mapper.xml文件
- SpringMVC 学谈 (第四章)
- 鸿蒙OS内核分析|解读鸿蒙源码
- 厦大C语言上机1381
- STM32片上外设时钟使能、失能和复位的区别
- 养生医学背景PPT模板
- 敲七 STL队列(c++)