有时候业务需要,需记录一条记录的修改历史,但是不能为完成任务而硬编码,不靠谱

这种情况可以使用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 记录对象前后修改的内容(工具类)相关推荐

  1. java excel 取值_java实现Excel 单元格取值工具类

    在工作中经常遇到通过excel获取数据的需求,比如通过excel将数据提交到数据库等.现针对excel单元格的取值方法提取出来作为一个工具类. 具体代码如下: import org.apache.po ...

  2. Java利用反射封装DBUtil,mysql万能增删改查工具类,附源码

    Java利用反射封装DBUtil,mysql万能增删改查工具类,附源码 等有时间再慢慢写代码注释吧,先把源码放出来.文章最后有整个项目的压缩包. ps:拓展 Java 原生MySQL JDBC 插入后 ...

  3. Java中Date类型如何向前向后滚动时间,( 附工具类)

    Java中的Date类型向前向后滚动时间(附工具类) 废话不多说,先看工具类: 1 import java.text.SimpleDateFormat; 2 import java.util.Cale ...

  4. string修饰的梦修改吗_Java String 对象,你真的了解了吗?

    String 对象的实现 String对象是 Java 中使用最频繁的对象之一,所以 Java 公司也在不断的对String对象的实现进行优化,以便提升String对象的性能,看下面这张图,一起了解一 ...

  5. 解决修改properties 属性文件存在缓存问题,附带操作properties文件工具类

    2019独角兽企业重金招聘Python工程师标准>>> 在做项目的时候有些数据不一定需要在数据库管理,例如数据库连接,定时任务等等的配置..有时候需要动态修改这些数据,但在修改完后, ...

  6. java 静态资源变量_Java中读取配置文件中的内容,并将其赋值给静态变量的方法...

    项目开发中某个功能需要抽取成方法写成一个工具类,提供给别人使用.写过工具类的人都知道,工具类中的方法一般都是静态方法,可以直接使用类名点方法名调用, 使用很方便,比如判断某个对象是否为空的方式Obje ...

  7. java 判断对象是否为空的工具类_如何判断java对象是否为空

    首先来看一下工具StringUtils的判断方法: 一种是org.apache.commons.lang3包下的:另一种是org.springframework.util包下的.这两种StringUt ...

  8. java 解压缩 工具类_Java实现的zip压缩及解压缩工具类示例

    本文实例讲述了Java实现的zip压缩及解压缩工具类.分享给大家供大家参考,具体如下: import java.io.BufferedInputStream; import java.io.Buffe ...

  9. java spring文件下载_SpringMVC实现文件上传和下载的工具类

    本文主要目的是记录自己基于SpringMVC实现的文件上传和下载的工具类的编写,代码经过测试可以直接运行在以后的项目中. 开发的主要思路是对上传和下载文件进行抽象,把上传和下载的核心功能抽取出来分装成 ...

最新文章

  1. 佛媛之后又产“新妖”,抖音、快手出马,依旧掐不灭鬼怪们的妖火
  2. 使用maven聚合安装多个maven工程到本地仓库报错的解决方法:child module pom.xml does not exist
  3. 不修条地铁,都不好意思叫自己大城市
  4. 从零开始学习音视频编程技术(七) FFMPEG Qt视频播放器之SDL的使用
  5. 美团外卖小哥被殴一事后续来了 警方通报涉事男子已被刑事拘留
  6. mysql将最大金额加1000_Mysql数据库笔记
  7. RVM,RubyGems和Bundler的日常使用
  8. src refspec main does not match any
  9. HDU1754 I Hate It(树状数组 or 线段树)
  10. 协同过滤算法_从网易云日推浅谈个性化推荐系统(1)——基于用户的协同过滤算法...
  11. Netty框架介绍及实战
  12. aspUpload有组件上传文件
  13. Mysql之auto_increment(自动增长)
  14. 由于没有公钥,无法验证下列签名: NO_PUBKEY 4F4EA0AAE5267A6C
  15. calico网络模型中的路由原理
  16. 什么是项目管理中的里程碑?如何实践?
  17. SAP_FICO常用事务代码
  18. 小爬虫爬取小猫咪图片并存入本地文件夹
  19. 11.0_[Java 继承]-继承/重写/抽象类/抽象方法/ final 修饰符
  20. 中国女排世界排名跌至第二,为何排名下跌?郎平这样回答

热门文章

  1. web安全101之如何理解XXE?
  2. 2021年云安全威胁预测,懂网络安全的无需恐慌
  3. 记录 grafana登录 从 go 迁移到 php
  4. C++中的字符串的部分功能
  5. 1.16 static关键字(静态变量和静态方法)
  6. 1.11 对象的销毁
  7. 1.20 实例:数字转人民币读法
  8. 第三章 搜索与图论 【完结】
  9. Shell中的while语句
  10. shell预定义变量