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