package com.yanzuoguang.util.base; import com.yanzuoguang.util.exception.ExceptionHelper; import com.yanzuoguang.util.helper.StringHelper; import java.lang.reflect.*; import java.util.*; /** * 对象操作类,包含字段反射 * * @author 颜佐光 */ public class ObjectHelper { public static final String METHOD_IS = "is"; public static final String METHOD_GET = "get"; public static final String METHOD_SET = "set"; /** * 缓存的类型 */ private static Map<Class<?>, HashMap<String, MethodField>> mapCache = new HashMap<>(); // --------------------------------------------- 类型判断 --------------------------------------------------------- /** * 判断类型间是否可以自动转换 * * @param to 需要转换后的类型 * @param from 转换前的类型 * @return */ public static boolean isAutoConvert(Class to, Class from) { return from != to && (Number.class.isAssignableFrom(to) || to.isEnum() || to == String.class); } /** * 判断from参数是否是to的子类 * * @param to 父类 * @param from 子类 * @return 是否满足条件 */ public static boolean isSub(Class to, Class from) { return from == to || from.isAssignableFrom(to); } /** * 判断值是否能够写入当前类型的对象 * * @param cls 类型 * @param value 值 * @return 是否能够写入 */ public static boolean isWriteType(Class<?> cls, Object value) { if (cls.isEnum() || cls.isAssignableFrom(Number.class)) { return true; } if (cls == String.class || cls == int.class || cls == boolean.class || cls == double.class || cls == float.class) { return true; } boolean isEmpty = StringHelper.isEmpty(value); if (isEmpty) { return true; } return cls.isAssignableFrom(value.getClass()); } // --------------------------------------------- 类型判断 --------------------------------------------------------- /** * 获取指定对象中某个字段的整形值 * * @param target 需要处理的对象 * @param field 需要获取的字段的值 * @return 返回值 */ public static int getInt(Object target, String field) { return StringHelper.toInt(get(target, field)); } /** * 获取指定对象中某个字段字符串值 * * @param target 需要处理的对象 * @param field 需要获取的字段的值 * @return 返回值 */ public static String getString(Object target, String field) { return get(String.class, target, field); } /** * 获取指定对象中某个字段的double值 * * @param target 需要处理的对象 * @param field 需要获取的字段的值 * @return 返回值 */ public static double getDecimal(Object target, String field) { return StringHelper.toDouble(get(target, field)); } /** * 类型转换(从obj中取出关键词为vName的值 , 转换为cls类型) * * @param cls 转换后的类型 * @param target 要转换对象 * @param field 要转换对象的关键词 * @return 返回值 */ public static <T> T get(Class<T> cls, Object target, String field) { return get(cls, target, field, null); } /** * 类型转换(从obj中取出关键词为vName的值 , 转换为cls类型) * * @param cls 转换后的类型 * @param target 要转换对象 * @param field 要转换对象的关键词 * @return 返回值 */ public static <T> T get(Class<T> cls, Object target, String field, T def) { Object val = get(target, field); T to = StringHelper.to(cls, val); to = to == null ? def : to; return to; } /** * 获取对象中的某个字段值,根据不同对象输出结果 * * @param target 需要获取的对象 * @param field 需要获取的字段 * @return 获取之后的值 */ public static Object get(Object target, String field) { Object ret = null; if (target == null) { return ret; } Class vType = target.getClass(); if (target instanceof Number || vType.isEnum()) { ret = null; } else if (target instanceof Map) { ret = ((Map) target).get(field); } else { ret = getByType(target.getClass(), target, field); } return ret; } /** * 获取对象的值(从obj中获取关键词为vName的值) * * @param targetCls 要获取的对象的Class类型 * @param target 要获取的对象 * @param field 要获取的对象的关键词 * @return 获取后的值 */ public static Object getByType(Class<?> targetCls, Object target, String field) { MethodField item = getMethodField(targetCls, field); if (item == null) { return null; } try { if (item.getField() != null && Modifier.isPublic(item.getField().getModifiers())) { return item.getField().get(target); } else if (item.getGetMethod() != null && Modifier.isPublic(item.getGetMethod().getModifiers())) { return item.getGetMethod().invoke(target); } } catch (Exception ex) { ExceptionHelper.handleException(ObjectHelper.class, ex, field); } return null; } /** * 设置对象中某个字段的值,根据不同类型设置不同值 * * @param target 需要设置的对象 * @param field 需要设置的字段 * @param value 需要设置的值 */ public static void set(Object target, String field, Object value) { if (target == null) { return; } Class vType = target.getClass(); if (target instanceof Number || vType.isEnum()) { return; } else if (target instanceof Map) { ((Map) target).put(field, value); } else { try { setByType(vType, target, field, value); } catch (Exception ex) { throw new RuntimeException(ex); } } } /** * 设置对象的值 * * @param targetCls 要赋值的类型 * @param target 要赋值的对象 * @param field 要赋值的方法 * @param value 值 */ public static void setByType(Class<?> targetCls, Object target, String field, Object value) { MethodField item = getMethodField(targetCls, field); if (item == null) { return; } try { setByType(target, item, value); } catch (Exception ex) { ExceptionHelper.handleException(ObjectHelper.class, ex, item.getName()); } } public static void setByType(Object target, MethodField item, Object value) throws IllegalAccessException, InvocationTargetException { if (item.getField() != null && Modifier.isPublic(item.getField().getModifiers())) { Class toType = item.getField().getType(); Object toValue = StringHelper.to(toType, value); item.getField().set(target, toValue); } else if (item.getSetMethod() != null && Modifier.isPublic(item.getSetMethod().getModifiers())) { Class toType = item.getSetMethod().getParameterTypes()[0]; Object toValue = StringHelper.to(toType, value); item.getSetMethod().invoke(target, toValue); } } // --------------------------------------------- 对象转换、复制、字段复制 --------------------------------------------------------- /** * 将对象复制成一个新的对象 * * @param from 需要复制的对象 * @param <T> 复制的对象的类型 * @return 新的对象 */ public static <T extends Object> T clone(T from) { if (from == null) { return from; } Class cls = from.getClass(); try { Object to = cls.newInstance(); writeWithFromClass(to, from); return (T) to; } catch (Exception e) { throw new RuntimeException("对象" + cls.getName() + "不能复制", e); } } /*** * 获取缓存中的字段 * @param typeCache 类型 * @param fromName 来源名称 * @param toName 目标名称 * @return */ private static MethodField getField(HashMap<String, MethodField> typeCache, String fromName, String toName) { if (!typeCache.containsKey(toName)) { MethodField newObj = new MethodField(); typeCache.put(toName, newObj); newObj.setName(fromName); newObj.setNameSimple(toName); } return typeCache.get(toName); } /** * 获取简单名称 * * @param fromName * @return */ private static String getSimpleName(String fromName) { String toName = getSimpleFieldName(fromName); if (toName.startsWith(METHOD_IS)) { toName = toName.substring(METHOD_IS.length()); } else if (toName.startsWith(METHOD_GET)) { toName = toName.substring(METHOD_GET.length()); } else if (toName.startsWith(METHOD_SET)) { toName = toName.substring(METHOD_SET.length()); } else { return toName; } return toName; } /** * 获取字段处理名称 * * @param fromName 字段名称 * @return 属性名称 */ private static String getSimpleFieldName(String fromName) { String toName = fromName.toLowerCase().replace("_", ""); return toName; } /** * 获取实体的字段 * * @param cls 需要获取的类型 * @return 获取字段之间的对应关系 */ private static HashMap<String, MethodField> getInitTypeField(Class<?> cls) { HashMap<String, MethodField> typeCache = new LinkedHashMap<String, MethodField>(); List<Field> fields = new ArrayList<Field>(); List<Method> methods = new ArrayList<Method>(); Class<?> tempClass = cls; //当父类为null的时候说明到达了最上层的父类(Object类). while (tempClass != null) { fields.addAll(Arrays.asList(tempClass.getDeclaredFields())); methods.addAll(Arrays.asList(tempClass.getDeclaredMethods())); //得到父类,然后赋给自己 tempClass = tempClass.getSuperclass(); } // 忽略大小写、忽略下划线 _ for (Field field : fields) { if (Modifier.isStatic(field.getModifiers())) { continue; } String toName = getSimpleFieldName(field.getName()); MethodField obj = getField(typeCache, field.getName(), toName); if (obj.getField() == null) { obj.setField(field); } } for (Method method : methods) { if (Modifier.isStatic(method.getModifiers())) { continue; } String methodNameSource = method.getName(); String methodNameSimple = methodNameSource.toLowerCase(); String toName = getSimpleName(methodNameSource); if ("getClass".equals(methodNameSource)) { continue; } else if (methodNameSimple.startsWith("set")) { if (method.getParameterTypes().length != 1) { continue; } MethodField obj = getField(typeCache, methodNameSource, toName); if (obj.getSetMethod() == null) { obj.setSetMethod(method); } } else if (methodNameSimple.startsWith("get")) { if (method.getReturnType() == null) { continue; } MethodField obj = getField(typeCache, methodNameSource, toName); if (obj.getGetMethod() == null) { obj.setGetMethod(method); } } else if (methodNameSimple.startsWith("is")) { if (method.getReturnType() == null) { continue; } MethodField obj = getField(typeCache, methodNameSource, toName); if (obj.getGetMethod() == null) { obj.setGetMethod(method); } } } return typeCache; } /** * 获取一个表中的字段 * * @param type * @return */ public static HashMap<String, MethodField> getTypeField(Class<?> type) { HashMap<String, MethodField> typeCache; if (mapCache.containsKey(type)) { typeCache = mapCache.get(type); } else { typeCache = getInitTypeField(type); mapCache.put(type, typeCache); } return typeCache; } /** * 获取字段的名称 * * @param type * @param name * @return */ private static MethodField getMethodField(Class<?> type, String name) { HashMap<String, MethodField> typeCache = getTypeField(type); name = getSimpleFieldName(name); return typeCache.containsKey(name) ? typeCache.get(name) : null; } /** * 将集合的类容转换为对象 * * @param vToClass 转换后的对象 * @param vTo 转换后的对象的集合 * @param vFrom 要转换的对象 * @param vField 关键词 * @throws Exception 需要跑出的异常 */ public static <T> void addList(Class<T> vToClass, ArrayList<T> vTo, Object vFrom, String vField) throws InstantiationException, IllegalAccessException { List vFroms = ObjectHelper.get(List.class, vFrom, vField); if (vFroms == null || vTo == null) { return; } for (Object vFromItem : vFroms) { T vToItem = ObjectHelper.convert(vToClass, vFromItem); vTo.add(vToItem); } } /** * 将来源类型的对象,转换为目标类型的对象 * * @param toCls 需要转换后的目标类型 * @param from 来源类型 * @param <T> 目标类型 * @return 转换后的值 * @throws IllegalAccessException 异常信息 * @throws InstantiationException 异常信息 */ public static <T> T convert(Class<T> toCls, Object from) throws IllegalAccessException, InstantiationException { if (from == null) { return null; } T to = StringHelper.to(toCls, from); if (to != null) { return to; } to = toCls.newInstance(); writeWithToClass(to, from); return to; } /** * 对象转换(一般将map转为javabean) * * @param to 转换后的对象 * @param from 要转换的对象 * @return 转换后的值 to */ public static Object writeWithToClass(Object to, Object from) { return writeWithToClass(false, to, from); } /** * 对象转换(一般将map转为javabean) * * @param emptyWrite 为空时是否写入 * @param to 转换后的对象 * @param from 要转换的对象 * @return 转换后的值 to */ public static Object writeWithToClass(boolean emptyWrite, Object to, Object from) { if (from == null || to == null) { return to; } HashMap<String, MethodField> mapField = getInitTypeField(to.getClass()); return writeWithClass(emptyWrite, to, from, mapField); } /** * 根据来源数据,往目标中写入数据 * * @param tos 目标对象 * @param froms 来源对象 */ public static void writeArrayWithFrom(List tos, Object... froms) { for (Object to : tos) { writeWithFrom(to, froms); } } /** * 根据来源数据,往目标中写入数据 * * @param tos 目标对象 * @param froms 来源对象 */ public static void writeArrayWithFrom(Object[] tos, Object... froms) { for (Object to : tos) { writeWithFrom(to, froms); } } /** * 根据来源数据,往目标中写入数据 * * @param to 目标对象 * @param froms 来源对象 */ public static void writeWithFrom(Object to, Object... froms) { for (Object from : froms) { if (from instanceof Map) { writeWithFromMap(to, (Map) from); } else { ObjectHelper.writeWithFromClass(to, from); } } } /** * 将值吸入到到目标数据 * * @param to 目标类型的数据 * @param from 来源类型的数据 * @return 写入之后的值 */ public static Object writeWithFromMap(Object to, Map from) { return writeWithFromMap(false, to, from); } /** * 将值吸入到到目标数据 * * @param emptyWrite 为空时是否写入 * @param to 目标类型的数据 * @param from 来源类型的数据 * @return 写入之后的值 */ public static Object writeWithFromMap(boolean emptyWrite, Object to, Map from) { for (Object key : from.keySet()) { Object fromValue = from.get(key); if (StringHelper.isEmpty(fromValue)) { continue; } ObjectHelper.set(to, StringHelper.toString(key), fromValue); } return to; } /** * 根据来源类型的字段,将数据写入目标类型的数据,为空时不写入 * * @param to 目标类型的数据 * @param from 来源类型的数据 * @return 写入之后的值 */ public static Object writeWithFromClass(Object to, Object from) { return writeWithFromClass(false, to, from); } /** * 根据来源类型的字段,将数据写入目标类型的数据 * * @param emptyWrite 为空时是否写入 * @param to 目标类型的数据 * @param from 来源类型的数据 * @return 写入之后的值 */ public static Object writeWithFromClass(boolean emptyWrite, Object to, Object from) { if (from == null || to == null) { return to; } HashMap<String, MethodField> mapField = getInitTypeField(from.getClass()); return writeWithClass(emptyWrite, to, from, mapField); } /** * 根据字段类型写入值 * * @param emptyWrite 为空时是否写入 * @param to 目标类型的数据 * @param from 来源类型的数据 * @param mapField 需要写入的字段 * @return 写入之后的值 */ private static Object writeWithClass(boolean emptyWrite, Object to, Object from, HashMap<String, MethodField> mapField) { if (from == null || to == null) { return to; } for (Map.Entry<String, MethodField> field : mapField.entrySet()) { String name = field.getValue().getName(); Object fromValue = ObjectHelper.get(from, name); if (StringHelper.isEmpty(fromValue)) { continue; } ObjectHelper.set(to, name, fromValue); } return to; } /** * 将对象转换为指定列表 * * @param cls 需要转换后的结果类型 * @param froms 需要转换后的值 * @param <T> 转换的类型 * @return 转换后的结果 */ public static <T> ArrayList<T> getList(Class<T> cls, Object froms) { ArrayList<T> tos = new ArrayList<T>(); if (froms instanceof List) { List vCodeFrom = (List) froms; for (Object from : vCodeFrom) { if (StringHelper.isEmpty(from)) { continue; } T to = StringHelper.to(cls, from); tos.add(to); } } else { if (!StringHelper.isEmpty(froms)) { T to = StringHelper.to(cls, froms); tos.add(to); } } return tos; } /** * 将对象转换为数组 * * @param froms 需要转换的数组 * @return 数组类型 */ public static <T extends Object> T[] getArray(T... froms) { return froms; } /** * 动态创建数组 * * @param cls 数组类型 * @param length 长度 * @param <T> 泛型 * @return 数组长度 */ public static <T extends Object> T[] createArray(Class<?> cls, int length) { Object array = Array.newInstance(cls, length); return (T[]) array; } }