java属性修改前后_java 记录对象前后修改的内容(工具类)
有时候业务需要,需记录一条记录的修改历史,但是不能为完成任务而硬编码,不靠谱
这种情况可以使用java反射来完成
对对象属性的描述可以通过自定义注解来完成,读取里面的属性进而记录修改历史。
在对象的属性上面加上注解,value设置为属性的中文描述
工具了代码如下
util类(BeanChangeUtil)
importjava.beans.PropertyDescriptor;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Arrays;public class BeanChangeUtil{publicString contrastObj(Object oldBean, Object newBean) {//创建字符串拼接对象
StringBuilder str = newStringBuilder();//转换为传入的泛型T
T pojo1 =(T) oldBean;
T pojo2=(T) newBean;//通过反射获取类的Class对象
Class clazz =pojo1.getClass();//获取类型及字段属性
Field[] fields =clazz.getDeclaredFields();returnjdk8Before(fields, pojo1, pojo2, str,clazz);//return jdk8OrAfter(fields, pojo1, pojo2, str,clazz);
}//jdk8 普通循环方式
publicString jdk8Before(Field[] fields,T pojo1,T pojo2,StringBuilder str,Class clazz){int i = 1;try{for(Field field : fields) {if(field.isAnnotationPresent(PropertyMsg.class)){
PropertyDescriptor pd= newPropertyDescriptor(field.getName(), clazz);//获取对应属性值
Method getMethod =pd.getReadMethod();
Object o1=getMethod.invoke(pojo1);
Object o2=getMethod.invoke(pojo2);if (o1 == null || o2 == null) {continue;
}if (!o1.toString().equals(o2.toString())) {
str.append(i+ "、" + field.getAnnotation(PropertyMsg.class).value() + ":" + "修改前=>" + o1 + ",修改后=>" + o2 + "\n");
i++;
}
}
}
}catch(Exception e) {
e.printStackTrace();
}returnstr.toString();
}//lambda表达式,表达式内部的变量都是final修饰,需要传入需要传入final类型的数组
publicString jdk8OrAfter(Field[] fields, T pojo1, T pojo2, StringBuilder str, Class clazz){final int[] i = {1};
Arrays.asList(fields).forEach(f->{if(f.isAnnotationPresent(PropertyMsg.class)){try{
PropertyDescriptor pd= newPropertyDescriptor(f.getName(), clazz);//获取对应属性值
Method getMethod =pd.getReadMethod();
Object o1=getMethod.invoke(pojo1);
Object o2=getMethod.invoke(pojo2);if (o1 == null || o2 == null) {return;
}if (!o1.toString().equals(o2.toString())) {
str.append(i[0] + "、" + f.getAnnotation(PropertyMsg.class).value() + ":" + "修改前=>" + o1 + "\t修改后=>" + o2 + "\n");
i[0]++;
}
}catch(Exception e){
e.printStackTrace();
}
}
});returnstr.toString();
}
}
自定义注解(PropertyMsg)
@Target
表示该注解可以用于什么地方,可能的ElementType参数有:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
@Retention
表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息。
@Document
将注解包含在Javadoc中
@Inherited
允许子类继承父类中的注解
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inheritedpublic @interfacePropertyMsg {
String value();
}
使用方式test
public classTestChange {public static voidmain(String[] args) {
TestChange u1= new TestChange("我是谁", "ok", 30,"刘德华");
TestChange u2= new TestChange("我在哪", "no", 20,"郭富城");
BeanChangeUtil t = new BeanChangeUtil<>();
String str=t.contrastObj(u1, u2);if (str.equals("")) {
System.out.println("未有改变");
}else{
System.out.println(str);
}
}publicTestChange() {
}publicTestChange(String about, String lock, Integer age, String name) {this.about =about;this.lock =lock;this.age =age;this.name =name;
}
@PropertyMsg("关于")privateString about;privateString lock;
@PropertyMsg("年龄")privateInteger age;
@PropertyMsg("姓名")privateString name;
get... set... 省略
}
OK,到位
原文出处:https://www.cnblogs.com/chywx/p/10634547.html
java属性修改前后_java 记录对象前后修改的内容(工具类)相关推荐
- java excel 取值_java实现Excel 单元格取值工具类
在工作中经常遇到通过excel获取数据的需求,比如通过excel将数据提交到数据库等.现针对excel单元格的取值方法提取出来作为一个工具类. 具体代码如下: import org.apache.po ...
- Java利用反射封装DBUtil,mysql万能增删改查工具类,附源码
Java利用反射封装DBUtil,mysql万能增删改查工具类,附源码 等有时间再慢慢写代码注释吧,先把源码放出来.文章最后有整个项目的压缩包. ps:拓展 Java 原生MySQL JDBC 插入后 ...
- Java中Date类型如何向前向后滚动时间,( 附工具类)
Java中的Date类型向前向后滚动时间(附工具类) 废话不多说,先看工具类: 1 import java.text.SimpleDateFormat; 2 import java.util.Cale ...
- string修饰的梦修改吗_Java String 对象,你真的了解了吗?
String 对象的实现 String对象是 Java 中使用最频繁的对象之一,所以 Java 公司也在不断的对String对象的实现进行优化,以便提升String对象的性能,看下面这张图,一起了解一 ...
- 解决修改properties 属性文件存在缓存问题,附带操作properties文件工具类
2019独角兽企业重金招聘Python工程师标准>>> 在做项目的时候有些数据不一定需要在数据库管理,例如数据库连接,定时任务等等的配置..有时候需要动态修改这些数据,但在修改完后, ...
- java 静态资源变量_Java中读取配置文件中的内容,并将其赋值给静态变量的方法...
项目开发中某个功能需要抽取成方法写成一个工具类,提供给别人使用.写过工具类的人都知道,工具类中的方法一般都是静态方法,可以直接使用类名点方法名调用, 使用很方便,比如判断某个对象是否为空的方式Obje ...
- java 判断对象是否为空的工具类_如何判断java对象是否为空
首先来看一下工具StringUtils的判断方法: 一种是org.apache.commons.lang3包下的:另一种是org.springframework.util包下的.这两种StringUt ...
- java 解压缩 工具类_Java实现的zip压缩及解压缩工具类示例
本文实例讲述了Java实现的zip压缩及解压缩工具类.分享给大家供大家参考,具体如下: import java.io.BufferedInputStream; import java.io.Buffe ...
- java spring文件下载_SpringMVC实现文件上传和下载的工具类
本文主要目的是记录自己基于SpringMVC实现的文件上传和下载的工具类的编写,代码经过测试可以直接运行在以后的项目中. 开发的主要思路是对上传和下载文件进行抽象,把上传和下载的核心功能抽取出来分装成 ...
最新文章
- 佛媛之后又产“新妖”,抖音、快手出马,依旧掐不灭鬼怪们的妖火
- 使用maven聚合安装多个maven工程到本地仓库报错的解决方法:child module pom.xml does not exist
- 不修条地铁,都不好意思叫自己大城市
- 从零开始学习音视频编程技术(七) FFMPEG Qt视频播放器之SDL的使用
- 美团外卖小哥被殴一事后续来了 警方通报涉事男子已被刑事拘留
- mysql将最大金额加1000_Mysql数据库笔记
- RVM,RubyGems和Bundler的日常使用
- src refspec main does not match any
- HDU1754 I Hate It(树状数组 or 线段树)
- 协同过滤算法_从网易云日推浅谈个性化推荐系统(1)——基于用户的协同过滤算法...
- Netty框架介绍及实战
- aspUpload有组件上传文件
- Mysql之auto_increment(自动增长)
- 由于没有公钥,无法验证下列签名: NO_PUBKEY 4F4EA0AAE5267A6C
- calico网络模型中的路由原理
- 什么是项目管理中的里程碑?如何实践?
- SAP_FICO常用事务代码
- 小爬虫爬取小猫咪图片并存入本地文件夹
- 11.0_[Java 继承]-继承/重写/抽象类/抽象方法/ final 修饰符
- 中国女排世界排名跌至第二,为何排名下跌?郎平这样回答