package li.util; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 反射工具类,封装了一些反射方法 * * @author li (limingwei@mail.com) * @version 0.1.4 (2012-05-08) */ public class Reflect { /** * 根据传入的类名返回对应的Class对象 */ public static <T> Class<T> getType(String type) { try { return (Class<T>) Class.forName(type); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 构造一个新的实例,根据类型,参数类型列表和参数列表 */ public static <T> T born(Class<T> type, Class<?>[] argTypes, Object[] args) { try { return type.getConstructor(argTypes).newInstance(args); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 构造一个新的实例,根据类型和参数列表 */ public static <T> T born(Class<T> type, Object... args) { return born(type, typesOf(args), args); } /** * 构造一个新的实例,根据类型名,参数类型列表和参数列表 */ public static <T> T born(String type, Class<?>[] argTypes, Object[] args) { return (T) born(getType(type), argTypes, args); } /** * 构造一个新的实例,根据类型名和参数列表 */ public static <T> T born(String type, Object... args) { return (T) born(getType(type), typesOf(args), args); } /** * 得到一个方法,根据对象类型,方法名和参数类型列表 */ public static Method getMethod(Class<?> targetType, String methodName, Class<?>... argTypes) { try { Method method = targetType.getDeclaredMethod(methodName, argTypes);// 在当前类型中查找方法 method.setAccessible(true);// 设置可见性为true return method; } catch (Exception e) {// 在超类型中查找方法 if (Object.class == targetType.getSuperclass()) { throw new RuntimeException("NoSuchMethod " + targetType.getName() + "." + methodName + "(..)", e); } else { return getMethod(targetType.getSuperclass(), methodName, argTypes); } } } /** * 执行target的method方法,以args为参数 */ public static Object invoke(Object target, Method method, Object... args) { try { return method.invoke(target, args); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 执行target的methodName方法,args类型需要顺序匹配于argTypes */ public static Object invoke(Object target, String methodName, Class<?>[] argTypes, Object[] args) { return invoke(target, getMethod(target.getClass(), methodName, argTypes), args); } /** * 执行target的methodName方法,args为参数列表,不可以为null * * @param args 可以没有,表示方法无参数,不可以为null */ public static Object invoke(Object target, String methodName, Object... args) { return invoke(target, getMethod(target.getClass(), methodName, typesOf(args)), args); } /** * 执行targetType类型的methodName静态方法,args类型需要顺序匹配于argTypes */ public static Object call(String targetType, String methodName, Class<?>[] argTypes, Object[] args) { return invoke(null, getMethod(getType(targetType), methodName, argTypes), args); } /** * 执行targetType类型的methodName静态方法,args为参数列表,不可以为null */ public static Object call(String targetType, String methodName, Object... args) { return invoke(null, getMethod(getType(targetType), methodName, typesOf(args)), args); } /** * 得到所有属性,包括超类中的 * * @param type */ public static List<Field> getFields(Class<?> type) { List<Field> fields = new ArrayList<Field>(); Collections.addAll(fields, type.getDeclaredFields()); if (Object.class != type.getSuperclass()) {// 扫描超类的Field fields.addAll(getFields(type.getSuperclass())); } return fields; } /** * 得到一个targetType的名为fieldName的属性,或者它的超类的 */ public static Field getField(Class<?> targetType, String fieldName) { try { Field field = targetType.getDeclaredField(fieldName);// 在当前类型中得到属性 field.setAccessible(true);// 设置可操作性为true return field; } catch (Exception e) {// 如果当前类型中无这个属性,则从其超类中查找 if (Object.class == targetType.getSuperclass()) { throw new RuntimeException(targetType.getName() + "." + fieldName + " " + e, e); } else { return getField(targetType.getSuperclass(), fieldName); } } } /** * 探测一个属性的类型,从Setter或Field或Getter,有缓存不会多次执行 */ public static Class<?> fieldType(Class<?> targetType, String fieldName) { Class<?> fieldType = (Class<?>) Log.get("~!@#FIELD_TYPE#" + targetType + "#" + fieldName); if (null == fieldType) { String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method[] methods = targetType.getMethods(); for (Method method : methods) { if (1 == method.getParameterTypes().length && method.getName().equals(setterName)) { fieldType = method.getParameterTypes()[0];// 从setter探测 } } if (null == fieldType) { try { fieldType = getField(targetType, fieldName).getType(); } catch (Exception e) { try {// 从getter探测 fieldType = getMethod(targetType, "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1)).getReturnType(); } catch (Exception ex) {} } } Log.put("~!@#FIELD_TYPE#" + targetType + "#" + fieldName, fieldType); } return fieldType; } /** * 使用getter方法返回属性值 */ public static Object getByGetter(Object target, String fieldName) { try { String method = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method getter = getMethod(target.getClass(), method); return getter.invoke(target);// 使用Getter方法 } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 访问字段以读取属性值 */ public static Object getByField(Object target, String fieldName) { try { return getField(target.getClass(), fieldName).get(target); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 返回target的名为fieldName的属性的值,优先采用Getter方法,Field字段其次 */ public static Object get(Object target, String fieldName) { Integer getFlag = (Integer) Log.get("~!@#GETTER#" + target.getClass() + "#" + fieldName + "#get"); Object result = null; if (null == getFlag || getFlag.equals(0)) {// 第一次或出错 try { result = getByGetter(target, fieldName);// 使用Getter方法 Log.put("~!@#GETTER#" + target.getClass() + "#" + fieldName, 1); } catch (Exception e) {// 没有匹配的Getter方法 try { result = getByField(target, fieldName);// 通过属性访问 Log.put("~!@#GETTER#" + target.getClass() + "#" + fieldName, 2); } catch (Exception ex) {// 没有匹配的属性 if (target instanceof Map) {// 是Map类型 result = ((Map) target).get(fieldName);// 通过Map.get()方法 Log.put("~!@#GETTER#" + target.getClass() + "#" + fieldName, 3); } else { Log.put("~!@#GETTER#" + target.getClass() + "#" + fieldName, 0); throw new RuntimeException("Reflect.get() target=" + target + ",fieldName=" + fieldName + ", when getByGetter " + e.getMessage() + ", when getByField " + ex.getMessage());// 这里没有给出根异常信息 } } } } else if (getFlag.equals(1)) {// 通过Getter方法 result = getByGetter(target, fieldName);// 使用Getter方法 } else if (getFlag.equals(2)) {// 通过Field result = getByField(target, fieldName);// 通过属性访问 } else if (getFlag.equals(3)) {// 是Map result = ((Map) target).get(fieldName);// 通过Map.get()方法 } return result; } /** * 获取静态变量 */ public static Object getStatic(String type, String fieldName) { return getStatic(Reflect.getType(type), fieldName); } /** * 获取静态变量 */ public static Object getStatic(Class<?> type, String fieldName) { try { return getField(type, fieldName).get(null); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 访问setter方法给属性设值,没做类型转换 */ public static void setBySetter(Object target, String fieldName, Object value) { try { String method = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method setter = getMethod(target.getClass(), method, fieldType(target.getClass(), fieldName)); setter.invoke(target, value);// 使用Setter方法,这里没做类型转换 } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 访问字段以设值,有做类型转换 */ public static void setByField(Object target, String fieldName, Object value) { try { Field field = getField(target.getClass(), fieldName); field.set(target, Convert.toType(field.getType(), value));// 通过属性访问,这里有做类型转换 } catch (Exception e) { throw new RuntimeException("e=" + e + " target=" + target + " fieldName=" + fieldName + " value=" + value); } } /** * 设置 target的名为fieldName的属性的值为 value,优先采用Setter方法,Field字段其次 */ public static void set(Object target, String fieldName, Object value) { Integer setFlag = (Integer) Log.get("~!@#SETTER#" + target.getClass() + "#" + fieldName); if (null == setFlag || setFlag.equals(0)) {// 第一次或出错 try { setBySetter(target, fieldName, value);// 使用Setter方法 Log.put("~!@#SETTER#" + target.getClass() + "#" + fieldName, 1); } catch (Exception e) {// 没有匹配的Setter方法 try { setByField(target, fieldName, value);// 通过属性访问 Log.put("~!@#SETTER#" + target.getClass() + "#" + fieldName, 2); } catch (Exception ex) {// 没有这个属性 if (target instanceof Map) {// Map类型 ((Map) target).put(fieldName, value);// 通过Map.put()方法 Log.put("~!@#SETTER#" + target.getClass() + "#" + fieldName, 3); } else { Log.put("~!@#SETTER#" + target.getClass() + "#" + fieldName, 0); throw new RuntimeException("Reflect.set() target=" + target + ",fieldName=" + fieldName + ",when setBySetter " + e + ", when setByField " + ex, ex); } } } } else if (setFlag.equals(1)) {// 通过Setter方法 setBySetter(target, fieldName, value);// 使用Setter方法 } else if (setFlag.equals(2)) {// 通过Field setByField(target, fieldName, value);// 通过属性访问 } else if (setFlag.equals(3)) {// 是Map ((Map) target).put(fieldName, value);// 通过Map.put()方法,这里也没做类型转换 } } /** * 设置静态变量 */ public static void setStatic(String type, String fieldName, Object value) { setStatic(Reflect.getType(type), fieldName, value); } /** * 设置静态变量 */ public static void setStatic(Class<?> type, String fieldName, Object value) { try { getField(type, fieldName).set(null, value); } catch (Exception e) { throw new RuntimeException(e + " ", e); } } /** * 返回一些对象的类型数组 */ public static Class<?>[] typesOf(Object... objects) { Class<?>[] types = new Class[objects.length]; for (int i = 0; i < objects.length; i++) { types[i] = objects[i].getClass(); } return types; } /** * 进行对象属性浅层复制 * * @param src 源对象 * @param dest 目的对象 * @return 返回目的对象 */ public static <T> T copy(Object src, T dest) { List<li.model.Field> srcFields = li.model.Field.list(src.getClass(), false); for (li.model.Field srcField : srcFields) {// 迭代源对象中的每一个属性 Field destField = getField(src.getClass(), srcField.name);// 获取目标对象的同名属性 if (null != destField && !Modifier.isFinal(destField.getModifiers())) {// 目标对象中均有此属性且可写 set(dest, srcField.name, get(src, srcField.name)); } } if (src instanceof Map && dest instanceof Map) { ((Map) dest).putAll((Map) src); } return dest; } /** * 超类的泛型参数在子类中的实际类型 * * @param subType 子类类型 */ public static Type[] actualTypes(Class<?> subType) { try { return ((ParameterizedType) subType.getGenericSuperclass()).getActualTypeArguments(); } catch (Exception e) {// 不能转换为ParameterizedType或者数组越界的异常,探测他的超类 return Object.class == subType.getSuperclass() ? null : actualTypes(subType.getSuperclass()); } } /** * 得到一个方法的参数注解列表 */ public static <T extends Annotation> T[] argAnnotations(Method method, Class<T> annotationType) { T[] array = (T[]) Array.newInstance(annotationType, method.getParameterTypes().length);// 生成注解数组 Annotation[][] ats = method.getParameterAnnotations();// 所有参数注解的二维数组 for (int i = 0; i < ats.length; i++) {// 每一个参数的注解数组 for (Annotation at : ats[i]) {// 一个参数上的每一个注解 if (annotationType.isAssignableFrom(at.annotationType())) {// 如果注解类型是指定类型 array[i] = (T) at; break;// 跳出当前层循环,处理下一个参数 } } } return array; } /** * 获得传入的方法的形参名列表 */ public static String[] argNames(Method method) { String[] temp = (String[]) Log.get("~!@#ARGNAMES#" + method); if (null == temp) { temp = MethodParameterScaner.getParameterNames(method); Log.put("~!@#ARGNAMES#" + method, temp); } return temp; } /** * 郑重声明:此类来自Nutz的Wendal,感谢Wendal的无私奉献! 通过读取Class文件,获得方法形参名称列表 * * @author wendal(wendal1985@gmail.com) */ private static class MethodParameterScaner { /** * 获取Method的形参名称列表 * * @param method 需要解析的方法 * @return 形参名称列表,如果没有调试信息,将返回null */ private static String[] getParameterNames(Method method) { try { int size = method.getParameterTypes().length; if (size == 0) { return new String[0]; } StringBuilder key = new StringBuilder();// getDescriptor key.append(method.getName()).append(','); key.append('('); Class<?>[] types = method.getParameterTypes(); for (Class<?> klass : types) { getDescriptor(key, klass); } key.append(')'); getDescriptor(key, method.getReturnType()); InputStream inputStream = method.getDeclaringClass().getResourceAsStream("/" + method.getDeclaringClass().getName().replace('.', '/') + ".class"); List<String> list = getParamNameMap(inputStream).get(key.toString());// getParameterNames if (list != null && list.size() != size) { return list.subList(0, size).toArray(new String[0]); } return list.toArray(new String[0]); } catch (Throwable e) { throw new RuntimeException(e + " ", e); } } /** * 传入Class文件流,返回类的所有方法参数的MapList */ private static Map<String, List<String>> getParamNameMap(InputStream in) throws IOException { DataInputStream dis = new DataInputStream(new BufferedInputStream(in)); Map<String, List<String>> names = new HashMap<String, List<String>>(); Map<Integer, String> strs = new HashMap<Integer, String>(); dis.skipBytes(4);// Magic dis.skipBytes(2);// 副版本号 dis.skipBytes(2);// 主版本号 int constant_pool_count = dis.readUnsignedShort();// 读取常量池 for (int i = 0; i < (constant_pool_count - 1); i++) { byte flag = dis.readByte(); switch (flag) { case 7:// CONSTANT_Class: dis.skipBytes(2); break; case 9:// CONSTANT_Fieldref: case 10:// CONSTANT_Methodref: case 11:// CONSTANT_InterfaceMethodref: dis.skipBytes(2); dis.skipBytes(2); break; case 8:// CONSTANT_String: dis.skipBytes(2); break; case 3:// CONSTANT_Integer: case 4:// CONSTANT_Float: dis.skipBytes(4); break; case 5:// CONSTANT_Long: case 6:// CONSTANT_Double: dis.skipBytes(8); i++;// 必须跳过一个,这是class文件设计的一个缺陷,历史遗留问题 break; case 12:// CONSTANT_NameAndType: dis.skipBytes(2); dis.skipBytes(2); break; case 1:// CONSTANT_Utf8: int len = dis.readUnsignedShort(); byte[] data = new byte[len]; dis.read(data); strs.put(i + 1, new String(data, "UTF-8"));// 必然是UTF8的 break; case 15:// CONSTANT_MethodHandle: dis.skipBytes(1); dis.skipBytes(2); break; case 16:// CONSTANT_MethodType: dis.skipBytes(2); break; case 18:// CONSTANT_InvokeDynamic: dis.skipBytes(2); dis.skipBytes(2); break; default: throw new RuntimeException("Impossible!! flag=" + flag); } } dis.skipBytes(2);// 版本控制符 dis.skipBytes(2);// 类名 dis.skipBytes(2);// 超类 // 跳过接口定义 int interfaces_count = dis.readUnsignedShort(); dis.skipBytes(2 * interfaces_count);// 每个接口数据,是2个字节 // 跳过字段定义 int fields_count = dis.readUnsignedShort(); for (int i = 0; i < fields_count; i++) { dis.skipBytes(2); dis.skipBytes(2); dis.skipBytes(2); int attributes_count = dis.readUnsignedShort(); for (int j = 0; j < attributes_count; j++) { dis.skipBytes(2);// 跳过访问控制符 int attribute_length = dis.readInt(); dis.skipBytes(attribute_length); } } // 开始读取方法 int methods_count = dis.readUnsignedShort(); for (int i = 0; i < methods_count; i++) { dis.skipBytes(2); // 跳过访问控制符 String methodName = strs.get(dis.readUnsignedShort()); String descriptor = strs.get(dis.readUnsignedShort()); short attributes_count = dis.readShort(); for (int j = 0; j < attributes_count; j++) { String attrName = strs.get(dis.readUnsignedShort()); int attribute_length = dis.readInt(); if ("Code".equals(attrName)) { // 形参只在Code属性中 dis.skipBytes(2); dis.skipBytes(2); int code_len = dis.readInt(); dis.skipBytes(code_len); // 跳过具体代码 int exception_table_length = dis.readUnsignedShort(); dis.skipBytes(8 * exception_table_length); // 跳过异常表 int code_attributes_count = dis.readUnsignedShort(); for (int k = 0; k < code_attributes_count; k++) { int str_index = dis.readUnsignedShort(); String codeAttrName = strs.get(str_index); int code_attribute_length = dis.readInt(); if ("LocalVariableTable".equals(codeAttrName)) {// 形参在LocalVariableTable属性中 int local_variable_table_length = dis.readUnsignedShort(); List<String> varNames = new ArrayList<String>(local_variable_table_length); for (int l = 0; l < local_variable_table_length; l++) { dis.skipBytes(2); dis.skipBytes(2); String varName = strs.get(dis.readUnsignedShort()); dis.skipBytes(2); dis.skipBytes(2); if (!"this".equals(varName)) // 非静态方法,第一个参数是this varNames.add(varName); } names.put(methodName + "," + descriptor, varNames); } else dis.skipBytes(code_attribute_length); } } else dis.skipBytes(attribute_length); } } dis.close(); return names; } /** 本方法来源于ow2的asm库的Type类 */ private static void getDescriptor(final StringBuilder buf, final Class<?> c) { Class<?> d = c; while (true) { if (d.isPrimitive()) { char car; if (d == Integer.TYPE) { car = 'I'; } else if (d == Void.TYPE) { car = 'V'; } else if (d == Boolean.TYPE) { car = 'Z'; } else if (d == Byte.TYPE) { car = 'B'; } else if (d == Character.TYPE) { car = 'C'; } else if (d == Short.TYPE) { car = 'S'; } else if (d == Double.TYPE) { car = 'D'; } else if (d == Float.TYPE) { car = 'F'; } else /* if (d == Long.TYPE) */{ car = 'J'; } buf.append(car); return; } else if (d.isArray()) { buf.append('['); d = d.getComponentType(); } else { buf.append('L'); String name = d.getName(); int len = name.length(); for (int i = 0; i < len; ++i) { char car = name.charAt(i); buf.append(car == '.' ? '/' : car); } buf.append(';'); return; } } } } }