首页 > 代码库 > [原创]Java使用反射及自定义注解实现对象差异性比较
[原创]Java使用反射及自定义注解实现对象差异性比较
Java项目C中 有一处逻辑,对于资源数据(类型为ResourceItem,拥有int/double/boolean/String类型数十个字段),需要比对资源数据每次变更的差异,并描述出变更情况。并非所有的字段都需要比对,如id字段则不参与比对。
依次比对每一个字段编写代码比对,将是个重苦力活。高级语言给予了我们诸多便利,应当加以利用。
首先定义自己的注解,value值用作字段描述
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface RevisionColumn { String value();}
为ResourceItem所有待比对字段添加该注解,如
public class ResourceItem { private int id; private int revision; private ResourceItemStatus status; @RevisionColumn("节点") private String node; @RevisionColumn("是否物理隔离") private boolean physicalIsolation; @RevisionColumn("整机:单盘上限(%)") private int machineDiskLimit; //...}
介绍比对逻辑前,首先定义记录对象字段差异的实体类型
public class FieldChangeInfo implements Serializable{ private String propertyName; private String propertyHeader; private Object from; private Object to; public FieldChangeInfo() { } public FieldChangeInfo(String propertyName, String propertyHeader, Object from, Object to) { this.propertyName = propertyName; this.propertyHeader = propertyHeader; this.from = from; this.to = to; } @Override public boolean equals(Object obj) { if (!(obj instanceof FieldChangeInfo)) return false; if (obj == this) return true; FieldChangeInfo rhs = (FieldChangeInfo) obj; return new EqualsBuilder(). append(propertyName, rhs.propertyName). append(propertyHeader, rhs.propertyHeader). append(from, rhs.from). append(to, rhs.to). isEquals(); } public String getPropertyName() { return propertyName; } public void setPropertyName(String propertyName) { this.propertyName = propertyName; } public String getPropertyHeader() { return propertyHeader; } public void setPropertyHeader(String propertyHeader) { this.propertyHeader = propertyHeader; } public Object getFrom() { return from; } public void setFrom(Object from) { this.from = from; } public Object getTo() { return to; } public void setTo(Object to) { this.to = to; }}
Resource数据比对逻辑,实现如下工具方法
1、参数接受ResourceItem新旧两个对象
2、通过反射,class.getDeclaredFields获取类型的所有字段
3、调用Field实例的getAnnotation方法,获取RevisionColumn注解对象,若不为null,则说明该字段设置了该注解,进行比对
4、获取字段值,检测空引用,调用equals方法做值比对,出现不匹配,则创建FiledChangeInfo对象记录差异信息
5、返回差异信息集合
public static List<FieldChangeInfo> getResourceItemFieldChangeInfo(ResourceItem originalItem, ResourceItem updatedItem) { try { List<FieldChangeInfo> fieldChangeInfos = new LinkedList<>(); for (Field field : ResourceItem.class.getDeclaredFields()) { RevisionColumn revisionColumn = field.getAnnotation(RevisionColumn.class); if (revisionColumn != null) { field.setAccessible(true); Object originalValue = field.get(originalItem); Object updatedValue = field.get(updatedItem); if (originalValue =http://www.mamicode.com/= null && updatedValue =http://www.mamicode.com/= null) continue; if (originalValue =http://www.mamicode.com/= null || !originalValue.equals(updatedValue)){ FieldChangeInfo fieldChangeInfo = new FieldChangeInfo(); fieldChangeInfo.setFrom(originalValue); fieldChangeInfo.setTo(updatedValue); fieldChangeInfo.setPropertyName(field.getName()); fieldChangeInfo.setPropertyHeader(revisionColumn.value()); fieldChangeInfos.add(fieldChangeInfo); } } } return fieldChangeInfos; } catch (IllegalAccessException e) { throw new RuntimeException("检测ResourceItem字段变更时出现异常"); } }
若有必要,则可以稍加重构转换为泛型方法,支持何种数据类型的差异性检测
[原创]Java使用反射及自定义注解实现对象差异性比较
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。