class BeanUtils {

    public static <T> List<String> getModifiedFields(T src, T dst, String... ignoreFields) {
        Class clazz = src.getClass();
        Method[] methods = clazz.getMethods();
        List<String> ignoreFiledList = Arrays.asList(ignoreFields);
        List<String> modifiedFields = new ArrayList<String>();
        for (Method getterMethod : methods) { // 遍历目标对象的方法
            if (Modifier.isStatic(getterMethod.getModifiers())
                || !ReflectUtils.isBeanPropertyReadMethod(getterMethod)) {
                // 不是static方法， 是getter方法
                continue;
            }
            String propertyName = ReflectUtils.getPropertyNameFromBeanReadMethod(getterMethod);
            if (ignoreFiledList.contains(propertyName)) {
                // 忽略字段
                continue;
            }
            Class returnType = getterMethod.getReturnType();
            try { // 同时目标字段还需要有set方法
                Method setterMethod = ReflectUtils.getPropertySetterMethod(clazz, propertyName, returnType);
                if (setterMethod != null) {
                    Object srcVal = getterMethod.invoke(src); // 原始值
                    Object dstVal = getterMethod.invoke(dst); // 修改后值
                    if (srcVal == null) { // 左边为空
                        if (dstVal != null) {
                            modifiedFields.add(propertyName);
                        }
                    } else {
                        if (dstVal == null) { // 右边为空
                            modifiedFields.add(propertyName);
                        } else {
                            if (!srcVal.equals(dstVal)) { // 都不为空且不同
                                modifiedFields.add(propertyName);
                            }
                        }
                    }
                }
            } catch (Exception ignore) {
                // ignore 下一循环
            }
        }
        return modifiedFields;
    }

}