上一遍博文 , 简单介绍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 }