代码优化

This commit is contained in:
2026-05-17 09:32:34 +08:00
parent c41d91afc4
commit 689a9419e8
16 changed files with 321 additions and 136 deletions
+29 -9
View File
@@ -121,6 +121,19 @@ public abstract class AbstractContrastUtil<T> {
}
/**
* 遍历所有getter方法,逐一对比属性值,并将差异设入change对象
*
* @param getList getter方法名列表
* @param methodAccess reflectASM方法访问器
* @param origin 原始对象
* @param target 修改后的对象
* @param setList setter方法名列表
* @param originChange 原始对象变化部分
* @param targetChange 修改后对象变化部分
* @param <T> 对象类型
* @return 是否有属性发生变化
*/
private <T> boolean forContrast(List<String> getList, MethodAccess methodAccess, T origin, T target, List<String> setList,
T originChange, T targetChange) throws Exception {
boolean changed = false;
@@ -151,35 +164,39 @@ public abstract class AbstractContrastUtil<T> {
}
/**
* 根据属性值类型分发到对应的处理器进行对比
* 优先检查特殊类型,然后依次处理Collection、Map、基本类型和自定义类型
*/
private boolean contrastValue(Object originValue, Object targetValue, Object originChange, Object targetChange,
MethodAccess methodAccess, String setName) throws Exception {
//特殊拦截类型的处理
if (isSpecialType(originValue, targetValue)) {
return specialContract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
//处理Collection
if (originValue instanceof Collection || targetValue instanceof Collection) {
if (originValue instanceof Collection && targetValue instanceof Collection) {
return collectionContract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
//Map的处理
if (originValue instanceof Map || targetValue instanceof Map) {
if (originValue instanceof Map && targetValue instanceof Map) {
return mapContract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
//非自定义类的处理
if (originValue instanceof Collection || targetValue instanceof Collection
|| originValue instanceof Map || targetValue instanceof Map) {
return selfContract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
Boolean result = originContract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
if (null != result) {
return result;
}
//自定义类型的处理
return selfContract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
/**
* 获取Set方法集合
* 获取Get方法集合
*
* @param methodAccess MethodAccess
* @param tClass 类.class
@@ -199,7 +216,7 @@ public abstract class AbstractContrastUtil<T> {
/**
* 获取Get方法集合
* 获取Set方法集合
*
* @param methodAccess MethodAccess
* @param tClass 类.class
@@ -218,6 +235,9 @@ public abstract class AbstractContrastUtil<T> {
}
/**
* 构建指定类型(get/set)的方法名列表,并缓存
*/
private static <T> List<String> buildMethodList(String type, String[] methodNames, List<Method> methods, List<String> methodNameList,
ConcurrentHashMap<String, List<String>> methodCache, Class<T> tClass) {
for (String methodName : methodNames) {
+66 -10
View File
@@ -24,7 +24,7 @@ import static constant.Constant.SET;
* @description 通用的对象比较基本实现类
* @date 2020-1-5 16:00:00
*/
class ContrastUtil {
public class ContrastUtil {
/**
@@ -46,7 +46,7 @@ class ContrastUtil {
* @return 对比结果
*/
@SuppressWarnings("unchecked")
static <T> ContrastObject<T> contrast(T origin, T target) throws IllegalAccessException, InstantiationException {
public static <T> ContrastObject<T> contrast(T origin, T target) throws IllegalAccessException, InstantiationException {
//空的情况的判断
if (origin == null || target == null) {
return nullProcessor(origin, target);
@@ -88,6 +88,14 @@ class ContrastUtil {
return setContrastObject(origin, target, originChange, targetChange);
}
/**
* 处理基本类型和包装类型的对比(由Bootstrap ClassLoader加载的类)
*
* @param origin 原始对象
* @param target 修改后的对象
* @param <T> 对象类型
* @return 对比结果,无变化返回null
*/
@SuppressWarnings("unchecked")
private static <T> ContrastObject<T> originProcessor(T origin, T target) {
if (origin == target) {
@@ -96,6 +104,14 @@ class ContrastUtil {
return new ContrastObject(origin, target, origin, target);
}
/**
* 处理入参为null的情况
*
* @param origin 原始对象
* @param target 修改后的对象
* @param <T> 对象类型
* @return 对比结果,两者都为null返回null,否则返回包含非null一方的结果
*/
private static <T> ContrastObject<T> nullProcessor(T origin, T target) {
if (origin == null && target == null) {
return null;
@@ -108,6 +124,19 @@ class ContrastUtil {
return setContrastObject(origin, null, origin, null);
}
/**
* 遍历所有getter方法,逐一对比属性值,并将差异设入change对象
*
* @param getList getter方法名列表
* @param methodAccess reflectASM方法访问器
* @param origin 原始对象
* @param target 修改后的对象
* @param setList setter方法名列表
* @param originChange 原始对象变化部分
* @param targetChange 修改后对象变化部分
* @param <T> 对象类型
* @return 是否有属性发生变化
*/
private static <T> boolean forContrast(List<String> getList, MethodAccess methodAccess, T origin, T target, List<String> setList,
T originChange, T targetChange) throws InstantiationException,
IllegalAccessException {
@@ -139,6 +168,16 @@ class ContrastUtil {
return changed;
}
/**
* 组装对比结果对象
*
* @param origin 原始对象
* @param target 修改后的对象
* @param originChange 原始对象中发生变化的部分
* @param targetChange 修改后对象中发生变化的部分
* @param <T> 对象类型
* @return 对比结果
*/
private static <T> ContrastObject<T> setContrastObject(T origin, T target, T originChange, T targetChange) {
ContrastObject<T> contrastObject = new ContrastObject<>();
contrastObject.setOrigin(origin);
@@ -149,40 +188,45 @@ class ContrastUtil {
}
/**
* 根据属性值类型分发到对应的处理器进行对比
* 支持Collection、Map、基本类型和自定义类型的对比
*
* @param originValue get方法拿到的原始的值
* @param targetValue get方法拿到的变化的值
* @param originChange 新创建的原始变化对象
* @param targetChange 新创建的改变变化对象
* @param methodAccess reflectASM类
* @param setName set方法名
* @return 该属性是否发生变化
* @throws IllegalAccessException 异常
* @throws InstantiationException 异常
*/
private static boolean contrastValue(Object originValue, Object targetValue, Object originChange, Object targetChange,
MethodAccess methodAccess, String setName) throws IllegalAccessException, InstantiationException {
//处理Collection
if (originValue instanceof Collection || targetValue instanceof Collection) {
if (originValue instanceof Collection && targetValue instanceof Collection) {
return CollectionHandler.contract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
//Map的处理
if (originValue instanceof Map || targetValue instanceof Map) {
if (originValue instanceof Map && targetValue instanceof Map) {
return MapHandler.putValue(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
//非自定义类的处理
if (originValue instanceof Collection || targetValue instanceof Collection
|| originValue instanceof Map || targetValue instanceof Map) {
return SelfHandler.contract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
Boolean result = OriginHandler.contract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
if (null != result) {
return result;
}
//自定义类型的处理
return SelfHandler.contract(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
/**
* 获取Get方法集合
* 获取Set方法集合
*
* @param methodAccess MethodAccess
* @param tClass 类.class
@@ -200,6 +244,18 @@ class ContrastUtil {
return buildMethodList(SET, methodNames, methods, methodNameList, setMethodCache, tClass);
}
/**
* 构建指定类型(get/set)的方法名列表,并缓存
*
* @param type 方法类型前缀(get或set)
* @param methodNames reflectASM返回的所有方法名
* @param methods 反射获取的所有Method列表
* @param methodNameList 用于收集方法名的列表
* @param methodCache 方法名缓存Map
* @param tClass 类.class
* @param <T> T
* @return 过滤后的方法名列表
*/
private static <T> List<String> buildMethodList(String type, String[] methodNames, List<Method> methods, List<String> methodNameList,
ConcurrentHashMap<String, List<String>> methodCache, Class<T> tClass) {
for (String methodName : methodNames) {
@@ -217,7 +273,7 @@ class ContrastUtil {
}
/**
* 获取Set方法集合
* 获取Get方法集合
*
* @param methodAccess MethodAccess
* @param tClass 类.class
+11
View File
@@ -5,9 +5,17 @@ import handler.MapHandler;
import handler.OriginHandler;
/**
* AbstractContrastUtil的使用示例
* 该示例直接复用了ContrastUtil中的CollectionHandler、MapHandler、OriginHandler处理器
* 自定义类型(selfContract)和特殊类型(specialContract)的处理返回false,表示不进行深度对比
*
* @author 志军
*/
public class ContrastUtilExample<T> extends AbstractContrastUtil<T> {
/**
* 处理入参为null的情况:两者都为null返回null,否则返回非null一方的结果
*/
@Override
<T> ContrastObject<T> nullProcessor(T origin, T target) {
if (origin == null && target == null) {
@@ -21,6 +29,9 @@ public class ContrastUtilExample<T> extends AbstractContrastUtil<T> {
return setContrastObject(origin, null, origin, null);
}
/**
* 处理基本类型和包装类型的对比
*/
@Override
<T> ContrastObject<T> originProcessor(T origin, T target) {
if (origin == target) {
+4 -4
View File
@@ -81,10 +81,10 @@ public class ContrastObject<T> {
return false;
}
ContrastObject<?> that = (ContrastObject<?>) o;
return getOrigin().equals(that.getOrigin()) &&
getTarget().equals(that.getTarget()) &&
getOriginChange().equals(that.getOriginChange()) &&
getTargetChange().equals(that.getTargetChange());
return Objects.equals(getOrigin(), that.getOrigin()) &&
Objects.equals(getTarget(), that.getTarget()) &&
Objects.equals(getOriginChange(), that.getOriginChange()) &&
Objects.equals(getTargetChange(), that.getTargetChange());
}
@Override
-1
View File
@@ -7,5 +7,4 @@ public class Constant {
public static final String GET = "get";
public static final String SET = "set";
public static final String WELL_NUMBER = "#";
}
+3 -3
View File
@@ -43,10 +43,10 @@ public class CollectionHandler {
return false;
}
Class returnValue = originValue == null ? targetValue.getClass() : originValue.getClass();
Class<?> clazz = originValue == null ? targetValue.getClass() : originValue.getClass();
Object originCollection = CollectionUtil.buildDiffCollection(originValue, targetValue, returnValue);
Object changeCollection = CollectionUtil.buildDiffCollection(targetValue, originValue, returnValue);
Object originCollection = CollectionUtil.buildDiffCollection(originValue, targetValue, clazz);
Object changeCollection = CollectionUtil.buildDiffCollection(targetValue, originValue, clazz);
changed = CollectionUtils.isNotEmpty((Collection) originCollection) || CollectionUtils.isNotEmpty((Collection) changeCollection);
+15 -10
View File
@@ -6,7 +6,7 @@
package handler;
import com.esotericsoftware.reflectasm.MethodAccess;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.CollectionUtils;
import util.MapUtil;
import util.SetUtil;
@@ -25,8 +25,7 @@ public class MapHandler {
public static boolean putValue(Object originChange, Object targetChange, Object originValue, Object targetValue,
MethodAccess methodAccess, String setName) throws IllegalAccessException, InstantiationException {
//这边也只处理只有一个map可能为空的情况,全部为空在前面的方法做了处理
if (SelfHandler.isOneNull(originChange, originChange, targetValue, originValue, methodAccess, setName)) {
if (SelfHandler.isOneNull(originChange, targetChange, originValue, targetValue, methodAccess, setName)) {
return true;
}
//参数前置
@@ -52,25 +51,31 @@ public class MapHandler {
//得到不一致的key的集合.
List<Map.Entry> originList = SetUtil.findUnLikeValue(originEntry, targetEntry);
List<Map.Entry> changeList = SetUtil.findUnLikeValue(originEntry, targetEntry);
List<Map.Entry> changeList = SetUtil.findUnLikeValue(targetEntry, originEntry);
//计算changed的值
changed = changed || !CollectionUtils.isEmpty(originList) || !CollectionUtils.isEmpty(changeList);
//把不一致的值设置会新的Map中
MapUtil.putIfNotEmpty(originMap, originList);
MapUtil.putIfNotEmpty(targetMap, changeList);
//对对象进行设值
methodAccess.invoke(originChange, setName, originValue);
methodAccess.invoke(targetChange, setName, targetValue);
methodAccess.invoke(originChange, setName, originMap);
methodAccess.invoke(targetChange, setName, targetMap);
return changed;
}
/**
* 比较Map中同一个key对应的两个value,如果不相等则将差异设入对应的Map
*/
private static boolean putValue(Object value, Object tValue, Map<Object, Object> originMap,
Map<Object, Object> targetMap, Object key) {
if (value.equals(tValue)) {
if (value == null && tValue == null) {
return false;
}
originMap.put(key, value);
targetMap.put(key, tValue);
return true;
if (value == null || tValue == null || !value.equals(tValue)) {
originMap.put(key, value);
targetMap.put(key, tValue);
return true;
}
return false;
}
}
+10 -14
View File
@@ -17,31 +17,27 @@ public class OriginHandler {
public static Boolean contract(Object originChange, Object targetChange, Object originValue, Object targetValue,
MethodAccess methodAccess, String setName) {
Class returnValue = originValue == null ? targetValue.getClass() : originValue.getClass();
Class<?> clazz = originValue == null ? targetValue.getClass() : originValue.getClass();
try {
if (returnValue.getClassLoader() == null) {
return contractValue(originChange, targetChange, originValue, targetValue, methodAccess, setName);
} else {
//用来判断是否进行了比较
return null;
}
} catch (NullPointerException ex) {
//这边是处理Object类型
if (clazz.getClassLoader() == null) {
return contractValue(originChange, targetChange, originValue, targetValue, methodAccess, setName);
}
return null;
}
private static boolean contractValue(Object originChange, Object targetChange, Object originValue, Object targetValue,
MethodAccess methodAccess, String setName) {
boolean result = (originValue == null ? targetValue.equals(originChange) : originValue.equals(targetValue));
if (originValue == targetValue || result) {
return false;
} else {
if (originValue == null || targetValue == null) {
methodAccess.invoke(originChange, setName, originValue);
methodAccess.invoke(targetChange, setName, targetValue);
return true;
}
if (originValue.equals(targetValue)) {
return false;
}
methodAccess.invoke(originChange, setName, originValue);
methodAccess.invoke(targetChange, setName, targetValue);
return true;
}
}
+11
View File
@@ -28,6 +28,17 @@ public class SelfHandler {
return false;
}
/**
* 判断两个值是否其中一个为null(另一个不为null),如果是则将非null值设入对应的change对象
*
* @param originChange 原始变化对象
* @param targetChange 修改后变化对象
* @param originValue 原始值
* @param targetValue 修改后的值
* @param methodAccess reflectASM方法访问器
* @param setName set方法名
* @return 是否其中一个为null
*/
static boolean isOneNull(Object originChange, Object targetChange, Object originValue, Object targetValue, MethodAccess methodAccess, String setName) {
if (originValue == null) {
methodAccess.invoke(targetChange, setName, targetValue);
+11 -4
View File
@@ -8,7 +8,8 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Vector;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static constant.Constant.GET;
import static constant.Constant.SET;
@@ -19,7 +20,7 @@ import static constant.Constant.SET;
*/
public class CheckUtil {
private static Vector<String> vector = new Vector<>();
private static Set<String> checkedClassSet = ConcurrentHashMap.newKeySet();
/**
@@ -29,7 +30,7 @@ public class CheckUtil {
* @param zClass Class类
*/
public static void checkGetAndSetMethod(Class zClass) {
if (vector.contains(zClass.getName())) {
if (checkedClassSet.contains(zClass.getName())) {
return;
}
List<Field> fieldList = ClassUtil.getAllFieldWithSuper(zClass);
@@ -48,9 +49,12 @@ public class CheckUtil {
throw new NoSetMethodException();
}
}
vector.add(zClass.getName());
checkedClassSet.add(zClass.getName());
}
/**
* 校验setter方法的参数类型是否与字段类型匹配
*/
private static boolean setMethodParamCheck(Field field, String setMethodName, List<Method> methodList) {
for (Method method : methodList) {
if (method.getName().equals(setMethodName) && method.getParameterTypes()[0] == field.getType()) {
@@ -60,6 +64,9 @@ public class CheckUtil {
return false;
}
/**
* 提取方法名列表
*/
private static List<String> getMethodNameList(List<Method> methodList) {
List<String> methodNameList = Lists.newArrayList();
for (Method method : methodList) {
-50
View File
@@ -1,6 +1,5 @@
package util;
import com.esotericsoftware.reflectasm.MethodAccess;
import com.google.common.collect.Lists;
import java.lang.reflect.Field;
@@ -9,21 +8,12 @@ import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import static constant.Constant.*;
/**
* @author 志军
* @date 2020-1-5 16:00:00
* 其实你不用担心类似 ##<code>fieldCache.get(zClass.getName())</code>这样的代码在一个方法里面写了很多遍会处理多次
* <p>可以了解一下##方法内联
*/
public class ClassUtil {
/**
* 类名#方法 - 方法索引 缓存
*/
private static ConcurrentHashMap<String, Integer> cache = new ConcurrentHashMap<String, Integer>();
/**
* 类 - Field数组 缓存
*/
@@ -35,46 +25,6 @@ public class ClassUtil {
private static ConcurrentHashMap<String, List<Method>> methodCache = new ConcurrentHashMap<String, List<Method>>();
/**
* 获取get方法
*
* @param fieldName 类属性名称
* @param zClass 类.class
* @return GetMethod
*/
public static Integer getGetMethod(String fieldName, Class zClass) {
//获取下标的方式非常方便,本质上,如果使用getDeclareMethod方法,还需要考虑继承的问题
MethodAccess access = MethodAccess.get(zClass);
String getMethodName = GET + String.valueOf(fieldName.charAt(0)).toUpperCase() + fieldName.substring(1);
String keyName = zClass.getName() + WELL_NUMBER + getMethodName;
if (cache.get(keyName) == null) {
cache.put(keyName, access.getIndex(getMethodName));
return access.getIndex(getMethodName);
}
return cache.get(keyName);
}
/**
* 获取set方法
*
* @param fieldName 类属性名称
* @param zClass 类.class
* @return SetMethod
*/
public static Integer getSetMethod(String fieldName, Class zClass) {
String setMethodName = SET + String.valueOf(fieldName.charAt(0)).toUpperCase() + fieldName.substring(1);
String keyName = zClass.getName() + WELL_NUMBER + setMethodName;
MethodAccess access = MethodAccess.get(zClass);
if (cache.get(keyName) != null) {
return cache.get(keyName);
}
cache.put(keyName, access.getIndex(setMethodName));
return access.getIndex(setMethodName);
}
static List<Field> getAllFieldWithSuper(Class zClass) {
if (fieldCache.get(zClass.getName()) != null) {
return fieldCache.get(zClass.getName());
+2 -3
View File
@@ -16,9 +16,8 @@ public class CollectionUtil {
@SuppressWarnings("unchecked")
public static Collection buildDiffCollection(Object originValue, Object targetValue, Class returnValue) throws IllegalAccessException,
public static Collection buildDiffCollection(Object originValue, Object targetValue, Class collectionClass) throws IllegalAccessException,
InstantiationException {
//数组为空的判断这边需要考虑的只有一个为空另一个不为空,因为在外面已经进行了其他两种情况的处理了
if (null == targetValue) {
return (Collection) originValue;
}
@@ -26,7 +25,7 @@ public class CollectionUtil {
return null;
}
Object collection = returnValue.newInstance();
Object collection = collectionClass.newInstance();
for (Object value : (Collection) originValue) {
if (((Collection) targetValue).contains(value)) {
+1 -1
View File
@@ -5,7 +5,7 @@
package util;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.CollectionUtils;
import java.util.List;
import java.util.Map;
+7 -7
View File
@@ -9,13 +9,13 @@ public class ContractTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
// testSimple();
// testObject();
// testSimpleMap();
// testSimpleList();
// testListList();
// testListObject();
// testListObjectRewriteEqual();
testSimple();
testObject();
testSimpleMap();
testSimpleList();
testListList();
testListObject();
testListObjectRewriteEqual();
}
private static void testObject() throws InstantiationException, IllegalAccessException {