java通过反射+注解获取两个对象改变的内容
来源:互联网 发布:mysql sys refcursor 编辑:程序博客网 时间:2024/05/23 02:26
项目需要保存编辑日志,初始想法是每一个字段都判断一遍,后来发现每个类都要写一遍判断方法,如果增删字段会非常麻烦,最后的想法是通过注解+反射来完成这个判断
首先,定义一个注解类
package org.anno;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 自定义注解 *@Documented:指明该注解可以用于生成doc *@Inherited:该注解可以被自动继承 *@Retention:指明在什么级别显示该注解: * RetentionPolicy.SOURCE 注解存在于源代码中,编译时会被抛弃 RetentionPolicy.CLASS 注解会被编译到class文件中,但是JVM会忽略 RetentionPolicy.RUNTIME JVM会读取注解,同时会保存到class文件中 @Target:指明该注解可以注解的程序范围 ElementType.TYPE 用于类,接口,枚举但不能是注解 ElementType.FIELD 作用于字段,包含枚举值 ElementType.METHOD 作用于方法,不包含构造方法 ElementType.PARAMETER 作用于方法的参数 ElementType.CONSTRUCTOR 作用于构造方法 ElementType.LOCAL_VERIABLE 作用于本地变量或者catch语句 ElementType.ANNOTATION_TYPE 作用于注解 ElementType.PACKAGE 作用于包 */ @Documented@Target(ElementType.FIELD)@Inherited@Retention(RetentionPolicy.RUNTIME)public @interface Change { //字段名称 public String fieldName() default "字段:"; //分隔符 public String separator() default ","; //扩展字段 public String expand() default ""; //中间拼接字符 public String extra() default "改为"; //时间格式化类型 public String pattern() default "yyyy-MM-dd";}
其次,定义一个实体类
package org.entity;import java.util.Date;import org.anno.Change;public class User { @Change(fieldName="编号:") private int id; @Change(fieldName="姓名:") private String name; @Change(fieldName="生日:") private Date birth; @Change(fieldName="年龄",expand="岁") private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
最后
package org.test;import java.lang.reflect.Field;import java.text.SimpleDateFormat;import java.util.Date;import org.anno.Change;import org.entity.User;public class RefectTest { public static void main(String[] args) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); User u1 = new User(); u1.setId(1); u1.setName("张三"); u1.setBirth(sdf.parse("2017-08-16")); u1.setAge(1); User u2 = new User(); u2.setId(2); u2.setName("李四"); u2.setBirth(sdf.parse("2017-08-15")); u2.setAge(21); System.out.println(compare(u1,u2)); } @SuppressWarnings({ "rawtypes", "unchecked" }) public static String compare(Object co,Object mo)throws Exception{ StringBuilder sb = new StringBuilder(); if(null == co || null == mo){ return sb.toString(); } if(co.getClass() != mo.getClass()){ return sb.toString(); } //获取对象的class Class cc = co.getClass(); Class mc = mo.getClass(); //获取声明的变量 Field[] cfs = cc.getDeclaredFields(); Field[] mfs = mc.getDeclaredFields(); for (int i = 0; i < cfs.length; i++) { Field cfield = cfs[i]; for(int j = 0; j < mfs.length; j++){ Field mfield = mfs[j]; //判断两个变量名是否一致 if(cfield.getName().equals(mfield.getName())){ //判断变量是否有自定义注解 boolean flag = cfield.isAnnotationPresent(Change.class); if(flag){ //获取变量名称 String fieldName = cfield.getName(); //组合变量的对应get方法 getId String method = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1,fieldName.length()); //根据方法名称调用对象方法获取变量值 Object v1 = cc.getMethod(method).invoke(co); Object v2 = mc.getMethod(method).invoke(mo); //判断变量值是否为空 if(null == v1 || null == v2){ break; } //获取对象的自定义注解内容 Change f = cfield.getAnnotation(Change.class); //判断变量值是否相同 if(!v1.equals(v2)){ //拼接字符串,如编号:1改为2,姓名:张三改为李四, sb.append(f.fieldName()+getString(v1,f.pattern())+f.expand()+f.extra()+getString(v2,f.pattern())+f.expand()+f.separator()); break; } } } } } return sb.toString(); } /** * 变量处理 * @param str * @param pattern * @return */ public static String getString(Object str,String pattern){ if(str instanceof Date){ SimpleDateFormat sdf = new SimpleDateFormat(pattern); return sdf.format(str); } return str.toString(); }}
阅读全文
1 0
- java通过反射+注解获取两个对象改变的内容
- java 通过反射获取注解
- java 通过反射获取注解
- java-反射(1)-通过反射改变对象的属性
- Java通过反射获取自定义注解
- java 自定义注解annotation和通过反射获取注解
- Java通过反射获取和设置对象的属性值
- java通过反射获取对象的变量和变量值
- java通过Annotation对象获取注解属性的值
- java 反射通过类名获取对象
- java通过反射获取枚举对象
- java之通过反射获取类中的注解值
- Java反射之通过反射获取一个对象的方法信息
- java自学笔记————通过反射来获取注解的信息;
- Java中通过注解+反射拿到对象的属性和方法
- 通过反射改变对象中非公有字段的值
- java 注解annotation的使用,以及反射如何获取注解
- java 注解annotation的使用,以及反射如何获取注解
- html笔记
- PHP使用极光推送
- Python+Hadoop Streaming实现MapReduce任务
- Netty
- C语言:跨函数使用内存
- java通过反射+注解获取两个对象改变的内容
- JavaScript难点系列(五):执行上下文
- WebApi安全性 使用TOKEN+签名验证
- 用户体验中的“动机理论”
- Spring Boot的快速入门
- 微信支付之路
- 对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)解说
- 使用UltraISO(软碟通)制作U盘启动盘完整教程
- shell中for循环,读取一整行