您的位置:首页 > 编程语言 > Java开发

java反射快速入门(二)

2016-02-05 16:40 246 查看
上一遍博文 , 简单介绍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个属性呢?不能接受了吧~

二: 方案② 用反射

添加类型枚举

public static void main(String[] args) throws Exception {
UserXMLDO userXMLDO = new UserXMLDO();
userXMLDO.setId(1L);
userXMLDO.setName("威少");
userXMLDO.setPassword("三双无解");
userXMLDO.setHeight(1.90d);
userXMLDO.setWeight(85.5d);

String xml = UserXMLDO.toStringXML(userXMLDO);
System.out.println(xml);

UserXMLDO userXMLDO2 = UserXMLDO.toUserXMLDO(xml);
System.out.println(userXMLDO2);
}


View Code

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

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

toStringXML()、toUserXMLDO() 的实现

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

weight("weight", Double.class),

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

三、总结

相信比较上述两种方案后, 你会觉得反射有时特别好用, 让代码更加健硕, 但是也要记住, 不要一味盲目, 甚至刻意去使用反射, 因为性能差是反射的一大弊端!要权衡评估下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: