public class PojoConvertUtils {
private static Logger logger = LoggerFactory.getLogger(PojoConvertUtils.class);
/**
* 变量缓存
*/
private static final Map<String, Map<String, Field>> CACHEFIELDS = new ConcurrentHashMap<>();
/**
* 基本类型
*/
private static final Set<Class> BASICCLASS = new HashSet<>();
/**
* 泛型
*/
private static final Integer SECOND_T = 1<<1;
/**
* HashMap初始值大写16个元素
*/
private static final Integer DEFAULT_SIZE = 1<<4;
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 orig
* @param <T>
* @return
*/
public static <T> T convertPojo(Object orig, Class<T> targetClass) {
try {
if(orig==null) {
return null;
}
T target = targetClass.newInstance();
/** 获取源对象的所有变量 */
List<Field> fields = new ArrayList<>() ;
Class tempClass = orig.getClass();
while (tempClass != null) {
//当父类为null的时候说明到达了最上层的父类(Object类).
fields.addAll(Arrays.asList(tempClass .getDeclaredFields()));
//得到父类,然后赋给自己
tempClass = tempClass.getSuperclass();
}
//Field[] fields = orig.getClass().getDeclaredFields();
for (Field field : fields) {
if (isStatic(field)) {
continue;
}
/** 获取目标方法 */
Field targetField = getTargetField(targetClass, field.getName());
if (targetField == null) {
continue;
}
Object value = getFiledValue(field, orig);
if (value == null) {
continue;
}
Class type1 = field.getType();
Class type2 = targetField.getType();
//两个类型是否相同
boolean sameType = type1.equals(type2);
if (isBasicType(type1)) {
if (sameType) {
setFieldValue(targetField, target, value);
}
} else if (value instanceof Map && Map.class.isAssignableFrom(type2)) {
//对map
setMap((Map) value, field, targetField, target);
} else if (value instanceof Set && Set.class.isAssignableFrom(type2)) {
//对set
setCollection((Collection) value, field, targetField, target);
} else if (value instanceof List && List.class.isAssignableFrom(type2)) {
//对list
setCollection((Collection) value, field, targetField, target);
} else if (value instanceof Enum && Enum.class.isAssignableFrom(type2)) {
//对enum
setEnum((Enum) value, field, targetField, target);
} else if (value instanceof Date && Date.class.isAssignableFrom(type2)) {
//对日期类型,不处理如joda包之类的扩展时间,不处理calendar
setDate((Date) value, targetField, type2, target, sameType);
}
}
return target;
} catch (Throwable t) {
logger.error("转换失败:" + t.getMessage());
throw new RuntimeException(t.getMessage());
}
}
/**
* 获取字段值
*
* @param field
* @param obj
* @return
*/
private static Object getFiledValue(Field field, Object obj) throws IllegalAccessException {
//获取原有的访问权限
boolean access = field.isAccessible();
try {
//设置可访问的权限
field.setAccessible(true);
return field.get(obj);
} finally {
//恢复访问权限
field.setAccessible(access);
}
}
/**
* 设置方法值
*
* @param field
* @param obj
* @param value
* @throws IllegalAccessException
*/
private static void setFieldValue(Field field, Object obj, Object value) throws IllegalAccessException {
//获取原有的访问权限
boolean access = field.isAccessible();
try {
//设置可访问的权限
field.setAccessible(true);
field.set(obj, value);
} finally {
//恢复访问权限
field.setAccessible(access);
}
}
/**
* 转换list
*
* @param orig
* @param targetClass
* @param <T>
* @return
*/
public static <T> List<T> convertPojos(List orig, Class<T> targetClass) {
List<T> list = new ArrayList<>(orig.size());
for (Object object : orig) {
list.add(convertPojo(object, targetClass));
}
return list;
}
/**
* 设置Map
*
* @param value
* @param origField
* @param targetField
* @param targetObject
* @param <T>
*/
private static <T> void setMap(Map value, Field origField, Field targetField, T targetObject) throws IllegalAccessException, InstantiationException {
Type origType = origField.getGenericType();
Type targetType = targetField.getGenericType();
if (origType instanceof ParameterizedType && targetType instanceof ParameterizedType) {
//泛型类型
ParameterizedType origParameterizedType = (ParameterizedType) origType;
Type[] origTypes = origParameterizedType.getActualTypeArguments();
ParameterizedType targetParameterizedType = (ParameterizedType) targetType;
Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
if (origTypes != null && origTypes.length == SECOND_T && targetTypes != null && targetTypes.length == SECOND_T) {
//正常泛型,查看第二个泛型是否不为基本类型
Class clazz = (Class) origTypes[1];
if (!isBasicType(clazz) && !clazz.equals(targetTypes[1])) {
//如果不是基本类型并且泛型不一致,则需要继续转换
Set<Map.Entry> entries = value.entrySet();
Map targetMap = value.getClass().newInstance();
for (Map.Entry entry : entries) {
targetMap.put(entry.getKey(), convertPojo(entry.getValue(), (Class) targetTypes[1]));
}
setFieldValue(targetField, targetObject, targetMap);
return;
}
}
}
setFieldValue(targetField, targetObject, value);
}
/**
* 设置集合
*
* @param value
* @param origField
* @param targetField
* @param targetObject
* @param <T>
* @throws IllegalAccessException
* @throws InstantiationException
*/
private static <T> void setCollection(Collection value, Field origField, Field targetField, T targetObject) throws IllegalAccessException, InstantiationException {
Type origType = origField.getGenericType();
Type targetType = targetField.getGenericType();
if (origType instanceof ParameterizedType && targetType instanceof ParameterizedType) {
//泛型类型
ParameterizedType origParameterizedType = (ParameterizedType) origType;
Type[] origTypes = origParameterizedType.getActualTypeArguments();
ParameterizedType targetParameterizedType = (ParameterizedType) targetType;
Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
if (origTypes != null && origTypes.length == 1 && targetTypes != null && targetTypes.length == 1) {
//正常泛型,查看第二个泛型是否不为基本类型
Class clazz = (Class) origTypes[0];
if (!isBasicType(clazz) && !clazz.equals(targetTypes[0])) {
//如果不是基本类型并且泛型不一致,则需要继续转换
Collection collection = value.getClass().newInstance();
for (Object obj : value) {
collection.add(convertPojo(obj, (Class) targetTypes[0]));
}
setFieldValue(targetField, targetObject, collection);
return;
}
}
}
setFieldValue(targetField, targetObject, value);
}
/**
* 设置枚举类型
*
* @param value
* @param origField
* @param targetField
* @param targetObject
* @param <T>
*/
private static <T> void setEnum(Enum value, Field origField, Field targetField, T targetObject) throws Exception {
if (origField.equals(targetField)) {
setFieldValue(targetField, targetObject, value);
} else {
//枚举类型都具有一个static修饰的valueOf方法
Method method = targetField.getType().getMethod("valueOf", String.class);
setFieldValue(targetField, targetObject, method.invoke(null, value.toString()));
}
}
/**
* 设置日期类型
*
* @param value
* @param targetField
* @param targetFieldType
* @param targetObject
* @param <T>
*/
private static <T> void setDate(Date value, Field targetField, Class targetFieldType, T targetObject, boolean sameType) throws IllegalAccessException {
Date date = null;
if (sameType) {
date = value;
} else if (targetFieldType.equals(java.sql.Date.class)) {
date = new java.sql.Date(value.getTime());
} else if (targetFieldType.equals(Date.class)) {
date = new Date(value.getTime());
} else if (targetFieldType.equals(java.sql.Timestamp.class)) {
date = new java.sql.Timestamp(value.getTime());
}
setFieldValue(targetField, targetObject, date);
}
/**
* 获取适配方法
*
* @param clazz
* @param fieldName
* @return
*/
public static Field getTargetField(Class clazz, String fieldName) {
String classKey = clazz.getName();
Map<String, Field> fieldMap = CACHEFIELDS.get(classKey);
if (fieldMap == null) {
fieldMap = new HashMap<>(DEFAULT_SIZE);
//Field[] fields = clazz.getDeclaredFields();
/** 获取源对象的所有变量 */
List<Field> fields = new ArrayList<>() ;
Class tempClass = clazz;
while (tempClass != null) {
//当父类为null的时候说明到达了最上层的父类(Object类).
fields.addAll(Arrays.asList(tempClass .getDeclaredFields()));
//得到父类,然后赋给自己
tempClass = tempClass.getSuperclass();
}
for (Field field : fields) {
if (isStatic(field)) {
continue;
}
fieldMap.put(field.getName(), field);
}
CACHEFIELDS.put(classKey, fieldMap);
}
return fieldMap.get(fieldName);
}
/**
* 确实是否为基础类型
*
* @param clazz
* @return
*/
public static boolean isBasicType(Class clazz) {
return clazz.isPrimitive() || BASICCLASS.contains(clazz);
}
/**
* 判断变量是否有静态修饰符static
*
* @param field
* @return
*/
public static boolean isStatic(Field field) {
return (8 & field.getModifiers()) == 8;
}
}
工具类之对象转换工具POJO转换成目标类型(反射应用)
最新推荐文章于 2024-05-13 14:11:31 发布