VoAndEntityTrans

package com.example.demo.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class ObjectFactory {
	
	/**
	 * 变量缓存
	 */
	private static final Map<String, Map<String, Field>> cacheFields = new ConcurrentHashMap<>();
	private static final Set<Class<?>> basicClass = new HashSet<>();
	static {
		basicClass.add(Integer.class);
		basicClass.add(Character.class);
		basicClass.add(Byte.class);
		basicClass.add(Float.class);
		basicClass.add(Double.class);
		basicClass.add(Boolean.class);
		basicClass.add(Long.class);
		basicClass.add(Short.class);
		basicClass.add(String.class);
		basicClass.add(BigDecimal.class);
	}
	
	/**
	 * 两个对象之间的数据转换
	 * @param <T>
	 * @param sourceObject
	 * @param targetClazz
	 * @return
	 */
	@SuppressWarnings({ "unused", "rawtypes" })
	public static <T> T toTarget(Object sourceObject, Class<T> targetClazz) {
		try {
			T targetObject = targetClazz.newInstance();
			
			//获取源对象的所有变量
			Field[] sourceObjectFields = sourceObject.getClass().getDeclaredFields();
			if(null != sourceObjectFields) {
				for (Field sourceObjectField : sourceObjectFields) {
					if(isStatic(sourceObjectField)) {
						continue;
					}
					
					//获取目标成员变量
					Field targetObjectField = getTargetField(targetClazz, sourceObjectField.getName());
					if(null == targetObjectField) {
						continue;
					}
					
					//获取源对象成员变量值
					Object sourceObjectFieldValue = getsourceObjectFieldValue(sourceObjectField, sourceObject);
					if(null == sourceObjectField) {
						continue;
					}
					
					Class<?> sourceObjectFieldType = sourceObjectField.getType();
					Class<?> targetObjectFieldType = targetObjectField.getType();
					//判断两个类型是否相同
					boolean flag_fieldType = sourceObjectFieldType.equals(targetObjectFieldType);
					if(isBasicType(sourceObjectFieldType)) {
						if(flag_fieldType) {
							setTargetObjectFieldValue(targetObjectField, targetObject, sourceObjectFieldValue);
						}
					}else if(sourceObjectFieldValue instanceof Map && Map.class.isAssignableFrom(targetObjectFieldType)) {
						setTargetObjectFieldValueInMap((Map)sourceObjectFieldValue, sourceObjectField, targetObjectField, targetObject);
					}else if(sourceObjectFieldValue instanceof Set && Set.class.isAssignableFrom(targetObjectFieldType)) {
						setTargetObjectFieldValueInCollection((Collection)sourceObjectFieldValue, sourceObjectField, targetObjectField, targetObject);
					}else if(sourceObjectFieldValue instanceof List && List.class.isAssignableFrom(targetObjectFieldType)) {
						setTargetObjectFieldValueInCollection((Collection)sourceObjectFieldValue, sourceObjectField, targetObjectField, targetObject);
					}else if(sourceObjectFieldValue instanceof Enum && Enum.class.isAssignableFrom(targetObjectFieldType)) {
						setTargetObjectFieldValueInEnum((Enum)sourceObjectFieldValue, sourceObjectField, targetObjectField, targetObject);
					}else if(sourceObjectFieldValue instanceof Date && Date.class.isAssignableFrom(targetObjectFieldType)) {
						setTargetObjectFieldValueInDate((Date)sourceObjectFieldValue, targetObjectField, targetObjectFieldType, targetObject, flag_fieldType);
					}
				}
				return targetObject;
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 通过日期方式给目标成员变量赋值
	 * @param <T>
	 * @param sourceObjectFieldValue	源对象成员变量值
	 * @param targetObjectField			目标成员变量
	 * @param targetObjectFieldType		目标对象成员变量类型
	 * @param targetObject				目标对象
	 * @param flag_fieldType			目标和成员对象成员变量类型是否相同
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	private static <T> void setTargetObjectFieldValueInDate(Date sourceObjectFieldValue, Field targetObjectField,
			Class<?> targetObjectFieldType, T targetObject, boolean flag_fieldType) throws IllegalArgumentException, IllegalAccessException {
		Date date = null;
		if (flag_fieldType) {
			date = sourceObjectFieldValue;
		} else if (targetObjectFieldType.equals(java.sql.Date.class)) {
			date = new java.sql.Date(sourceObjectFieldValue.getTime());
		} else if (targetObjectFieldType.equals(java.util.Date.class)) {
			date = new Date(sourceObjectFieldValue.getTime());
		} else if (targetObjectFieldType.equals(java.sql.Timestamp.class)) {
			date = new java.sql.Timestamp(sourceObjectFieldValue.getTime());
		}
		setTargetObjectFieldValue(targetObjectField, targetObject, date);
	}
	/**
	 * 通过Enum方式给目标成员变量赋值
	 * @param <T>
	 * @param sourceObjectFieldValue	源对象成员变量值
	 * @param sourceObjectField			源对象成员变量
	 * @param targetObjectField			目标成员变量
	 * @param targetObject				目标对象
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 */
	@SuppressWarnings("rawtypes")
	private static <T> void setTargetObjectFieldValueInEnum(Enum sourceObjectFieldValue, Field sourceObjectField,
			Field targetObjectField, T targetObject) throws IllegalArgumentException, IllegalAccessException, NoSuchMethodException, SecurityException, InvocationTargetException {
		if(sourceObjectField.equals(targetObjectField)) {
			setTargetObjectFieldValue(targetObjectField, targetObject, sourceObjectFieldValue);
		}else {
			//枚举类型都具有一个static修饰的valueOf方法
			Method method = targetObjectField.getType().getMethod("valueOf", String.class);
			setTargetObjectFieldValue(targetObjectField, targetObject, method.invoke(null, sourceObjectFieldValue.toString()));
		}
	}

	/**
	 * 通过Map方式给目标成员变量赋值
	 * @param <T>
	 * @param sourceObjectFieldValue	源对象成员变量值
	 * @param sourceObjectField			源对象成员变量
	 * @param targetObjectField			目标成员变量
	 * @param targetObject				目标对象
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws InstantiationException 
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static <T> void setTargetObjectFieldValueInCollection(Collection sourceObjectFieldValue,
			Field sourceObjectField, Field targetObjectField, T targetObject) throws IllegalArgumentException, IllegalAccessException, InstantiationException {
		Type sourceObjectFieldType = sourceObjectField.getGenericType();
		Type targetObjectFieldType = targetObjectField.getGenericType();
		if(sourceObjectFieldType instanceof ParameterizedType && targetObjectFieldType instanceof ParameterizedType) {//泛型类型
			ParameterizedType sourceParameterizedType = (ParameterizedType) sourceObjectFieldType;
			Type[] sourceTypes = sourceParameterizedType.getActualTypeArguments();
			ParameterizedType targetParameterizedType = (ParameterizedType) targetObjectFieldType;
			Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
			if(null != sourceTypes && sourceTypes.length == 1 &&
					null != targetTypes && targetTypes.length == 1) {//正常泛型,查看第二个泛型是否不为基本类型
				Class sourceType = (Class) sourceTypes[0];
				if(!isBasicType(sourceType) && !sourceType.equals(targetTypes[0])) {//如果不是基本类型并且泛型不一致,则需要继续转换
					Collection collection = sourceObjectFieldValue.getClass().newInstance();
					for (Object obj : sourceObjectFieldValue) {
						collection.add(toTarget(obj, (Class)targetTypes[0]));
					}
					setTargetObjectFieldValue(targetObjectField, targetObject, collection);
					return ;
				}
			}
		}
		setTargetObjectFieldValue(targetObjectField, targetObject, sourceObjectFieldValue);
	}

	/**
	 * 通过Map方式给目标成员变量赋值
	 * @param <T>
	 * @param sourceObjectFieldValue	源对象成员变量值
	 * @param sourceObjectField			源对象成员变量
	 * @param targetObjectField			目标成员变量
	 * @param targetObject				目标对象
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static <T> void setTargetObjectFieldValueInMap(Map sourceObjectFieldValue, Field sourceObjectField,
			Field targetObjectField, T targetObject) throws InstantiationException, IllegalAccessException {
		Type sourceObjectFieldType = sourceObjectField.getGenericType();
		Type targetObjectFieldType = targetObjectField.getGenericType();
		if(sourceObjectFieldType instanceof ParameterizedType && targetObjectFieldType instanceof ParameterizedType) {//泛型类型
			ParameterizedType sourceParameterizedType = (ParameterizedType) sourceObjectFieldType;
			Type[] sourceTypes = sourceParameterizedType.getActualTypeArguments();
			ParameterizedType targetParameterizedType = (ParameterizedType) targetObjectFieldType;
			Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
			if(null != sourceTypes && sourceTypes.length == 2 &&
					null != targetTypes && targetTypes.length == 2) {//正常泛型,查看第二个泛型是否不为基本类型
				Class sourceType = (Class) sourceTypes[1];
				if(!isBasicType(sourceType) && !sourceType.equals(targetTypes[1])) {//如果不是基本类型并且泛型不一致,则需要继续转换
					Set<Map.Entry> entries = sourceObjectFieldValue.entrySet();
					Map targetMap = sourceObjectFieldValue.getClass().newInstance();
					for (Map.Entry entry : entries) {
						targetMap.put(entry.getKey(), toTarget(entry.getValue(),(Class)targetTypes[1]));
					}
					setTargetObjectFieldValue(targetObjectField, targetObject, targetMap);
					return ;
				}
			}
		}
		setTargetObjectFieldValue(targetObjectField, targetObject, sourceObjectFieldValue);
	}

	/**
	 * 为成员变量赋值
	 * @param targetObjectField	目标对象要赋值的成员变量
	 * @param targetObject	目标对象
	 * @param sourceObjectFieldValue	源对象成员变量的值
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	private static void setTargetObjectFieldValue(Field targetObjectField, Object targetObject, Object sourceObjectFieldValue) throws IllegalArgumentException, IllegalAccessException {
		//获取原有的访问权限
		boolean access = targetObjectField.isAccessible();
		try {
			//设置可访问的权限
			targetObjectField.setAccessible(true);
			targetObjectField.set(targetObject, sourceObjectFieldValue);
		}finally {
			//恢复访问权限
			targetObjectField.setAccessible(access);
		}
	}

	/**
	 * 判断源对象成员变量是否为基础类型
	 * @param clazz	源对象
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isBasicType(Class clazz) {
		
		return clazz.isPrimitive() || basicClass.contains(clazz);
	}

	/**
	 * 获取成员变量值
	 * @param sourceObjectField	源对象成员变量
	 * @param sourceObject	源对象
	 * @return
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	private static Object getsourceObjectFieldValue(Field sourceObjectField, Object sourceObject) throws IllegalArgumentException, IllegalAccessException {
		//获取原有的访问权限
		boolean access = sourceObjectField.isAccessible();
		try {
			//设置可访问的权限
			sourceObjectField.setAccessible(true);
			return sourceObjectField.get(sourceObject);
		}finally {
			//恢复访问权限
			sourceObjectField.setAccessible(access);
		}
	}

	/**
	 * 获取适配成员变量方法
	 * @param <T>
	 * @param targetClazz 目标对象
	 * @param sourceObjectFieldName 源对象字段名称
	 * @return
	 */
	public static <T> Field getTargetField(Class<T> targetClazz, String sourceObjectFieldName) {
		String targetClazzKey = targetClazz.getName();
		Map<String, Field> targetFieldMap = cacheFields.get(targetClazzKey);
		if(null == targetFieldMap) {
			targetFieldMap = new HashMap<>();
			Field[] targetFields = targetClazz.getDeclaredFields();
			if(null != targetFields) {
				for (Field targetField : targetFields) {
					if(isStatic(targetField)) {
						continue;
					}
					targetFieldMap.put(targetField.getName(), targetField);
				}
				cacheFields.put(targetClazzKey, targetFieldMap);
			}
		}
		return targetFieldMap.get(sourceObjectFieldName);
	}

	/**
	 * 判断成员变量是否有静态修饰符static
	 * @param field
	 * @return
	 */
	public static boolean isStatic(Field field) {
		return (8 & field.getModifiers()) == 8;
	}
}

  转载 https://blog.csdn.net/weixin_40584932/article/details/78601039

原文地址:https://www.cnblogs.com/zj68/p/13976788.html