code: public static void copyProperties(Object src, Object dst, String... ignoreFields) {
          Class srcClazz = src.getClass();
          Class distClazz = dst.getClass();
          Method[] methods = distClazz.getMethods();
          List<String> ignoreFiledList = Arrays.asList(ignoreFields);
          for (Method dstMethod : methods) { // 遍历目标对象的方法
              if (Modifier.isStatic(dstMethod.getModifiers())
                  || !ReflectUtils.isBeanPropertyReadMethod(dstMethod)) {
                  // 不是static方法， 是getter方法
                  continue;
              }
              String propertyName = ReflectUtils.getPropertyNameFromBeanReadMethod(dstMethod);
              if (ignoreFiledList.contains(propertyName)) {
                  // 忽略字段
                  continue;
              }
              Class dstReturnType = dstMethod.getReturnType();
              try { // 同时目标字段还需要有set方法
                  Method dstSetterMethod = ReflectUtils.getPropertySetterMethod(distClazz, propertyName, dstReturnType);
                  if (dstSetterMethod != null) {
                      // 再检查原始对象方法
                      Method srcGetterMethod = ReflectUtils.getPropertyGetterMethod(srcClazz, propertyName);
                      // 原始字段有getter方法
                      Class srcReturnType = srcGetterMethod.getReturnType();
                      if (srcReturnType.equals(dstReturnType)) { // 原始字段和目标字段返回类型一样
                          Object val = srcGetterMethod.invoke(src); // 从原始对象读取值
                          if (val != null) {
                              dstSetterMethod.invoke(dst, val); // 设置到目标对象
                          }
                      }
                  }
              } catch (Exception ignore) {
                  // ignore 下一循环
              }
          }
      }
docs: 从一个对象复制相同字段到另一个对象，（只写有getter/setter方法都有的值）
  
  @param src          原始对象
  @param dst          目标对象
  @param ignoreFields 忽略的字段