import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; /** * 反射工具类. * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. */ @SuppressWarnings("rawtypes") public class Reflections { private static final String SETTER_PREFIX = "set"; private static final String GETTER_PREFIX = "get"; private static final String CGLIB_CLASS_SEPARATOR = "$$"; private static Logger logger = LoggerFactory.getLogger(Reflections.class); /** * 调用Getter方法. * 支持多级,如:对象名.对象名.方法 */ public static Object invokeGetter(Object obj, String propertyName) { Object object = obj; for (String name : StringUtils.split(propertyName, ".")){ String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); } return object; } /** * 调用Setter方法, 仅匹配方法名。 * 支持多级,如:对象名.对象名.方法 */ public static void invokeSetter(Object obj, String propertyName, Object value) { Object object = obj; String[] names = StringUtils.split(propertyName, "."); for (int i=0; i<names.length; i++){ if(i<names.length-1){ String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); }else{ String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); invokeMethodByName(object, setterMethodName, new Object[] { value }); } } } /** * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. */ public static Object getFieldValue(final Object obj, final String fieldName) { Field field = getAccessibleField(obj, fieldName); if (field == null) { throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); } Object result = null; try { result = field.get(obj); } catch (IllegalAccessException e) { logger.error("不可能抛出的异常{}", e.getMessage()); } return result; } /** * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. */ public static void setFieldValue(final Object obj, final String fieldName, final Object value) { Field field = getAccessibleField(obj, fieldName); if (field == null) { throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); } try { field.set(obj, value); } catch (IllegalAccessException e) { logger.error("不可能抛出的异常:{}", e.getMessage()); } } /** * 直接调用对象方法, 无视private/protected修饰符. * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. * 同时匹配方法名+参数类型, */ public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes, final Object[] args) { Method method = getAccessibleMethod(obj, methodName, parameterTypes); if (method == null) { throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); } try { return method.invoke(obj, args); } catch (Exception e) { throw convertReflectionExceptionToUnchecked(e); } } /** * 直接调用对象方法, 无视private/protected修饰符, * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. * 只匹配函数名,如果有多个同名函数调用第一个。 */ public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { Method method = getAccessibleMethodByName(obj, methodName); if (method == null) { throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); } try { return method.invoke(obj, args); } catch (Exception e) { throw convertReflectionExceptionToUnchecked(e); } } /** * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. * * 如向上转型到Object仍无法找到, 返回null. */ public static Field getAccessibleField(final Object obj, final String fieldName) { Validate.notNull(obj, "object can't be null"); Validate.notBlank(fieldName, "fieldName can't be blank"); for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { try { Field field = superClass.getDeclaredField(fieldName); makeAccessible(field); return field; } catch (NoSuchFieldException e) {//NOSONAR // Field不在当前类定义,继续向上转型 continue;// new add } } return null; } /** * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. * 如向上转型到Object仍无法找到, 返回null. * 匹配函数名+参数类型。 * * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) */ public static Method getAccessibleMethod(final Object obj, final String methodName, final Class<?>... parameterTypes) { Validate.notNull(obj, "object can't be null"); Validate.notBlank(methodName, "methodName can't be blank"); for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { try { Method method = searchType.getDeclaredMethod(methodName, parameterTypes); makeAccessible(method); return method; } catch (NoSuchMethodException e) { // Method不在当前类定义,继续向上转型 continue;// new add } } return null; } /** * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. * 如向上转型到Object仍无法找到, 返回null. * 只匹配函数名。 * * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) */ public static Method getAccessibleMethodByName(final Object obj, final String methodName) { Validate.notNull(obj, "object can't be null"); Validate.notBlank(methodName, "methodName can't be blank"); for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { Method[] methods = searchType.getDeclaredMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { makeAccessible(method); return method; } } } return null; } /** * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 */ public static void makeAccessible(Method method) { if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { method.setAccessible(true); } } /** * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 */ public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier .isFinal(field.getModifiers())) && !field.isAccessible()) { field.setAccessible(true); } } /** * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 * 如无法找到, 返回Object.class. * eg. * public UserDao extends HibernateDao<User> * * @param clazz The class to introspect * @return the first generic declaration, or Object.class if cannot be determined */ @SuppressWarnings("unchecked") public static <T> Class<T> getClassGenricType(final Class clazz) { return getClassGenricType(clazz, 0); } /** * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. * 如无法找到, 返回Object.class. * * 如public UserDao extends HibernateDao<User,Long> * * @param clazz clazz The class to introspect * @param index the Index of the generic ddeclaration,start from 0. * @return the index generic declaration, or Object.class if cannot be determined */ public static Class getClassGenricType(final Class clazz, final int index) { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); return Object.class; } return (Class) params[index]; } public static Class<?> getUserClass(Object instance) { Assert.notNull(instance, "Instance must not be null"); Class clazz = instance.getClass(); if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { Class<?> superClass = clazz.getSuperclass(); if (superClass != null && !Object.class.equals(superClass)) { return superClass; } } return clazz; } /** * 将反射时的checked exception转换为unchecked exception. */ public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException || e instanceof NoSuchMethodException) { return new IllegalArgumentException(e); } else if (e instanceof InvocationTargetException) { return new RuntimeException(((InvocationTargetException) e).getTargetException()); } else if (e instanceof RuntimeException) { return (RuntimeException) e; } return new RuntimeException("Unexpected Checked Exception.", e); } }
法二:
import java.lang.reflect.Method; import java.util.Hashtable; import java.util.regex.Pattern; /** * * @desc 通过反射来动态调用get 和 set 方法 */ public class ReflectHelper { private Class cls; /** * 传过来的对象 */ private Object obj; /** * 存放get方法 */ private Hashtable<String, Method> getMethods = null; /** * 存放set方法 */ private Hashtable<String, Method> setMethods = null; /** * 定义构造方法 -- 一般来说是个pojo * * @param o * 目标对象 */ public ReflectHelper(Object o) { obj = o; initMethods(); } /** * * @desc 初始化 */ public void initMethods() { getMethods = new Hashtable<String, Method>(); setMethods = new Hashtable<String, Method>(); cls = obj.getClass(); Method[] methods = cls.getMethods(); // 定义正则表达式,从方法中过滤出getter / setter 函数. String gs = "get(\\w+)"; Pattern getM = Pattern.compile(gs); String ss = "set(\\w+)"; Pattern setM = Pattern.compile(ss); // 把方法中的"set" 或者 "get" 去掉 String rapl = "$1"; String param; for (int i = 0; i < methods.length; ++i) { Method m = methods[i]; String methodName = m.getName(); if (Pattern.matches(gs, methodName)) { param = getM.matcher(methodName).replaceAll(rapl).toLowerCase(); getMethods.put(param, m); } else if (Pattern.matches(ss, methodName)) { param = setM.matcher(methodName).replaceAll(rapl).toLowerCase(); setMethods.put(param, m); } else { // System.out.println(methodName + " 不是getter,setter方法!"); } } } /** * * @desc 调用set方法 */ public boolean setMethodValue(String property,Object object) { Method m = setMethods.get(property.toLowerCase()); if (m != null) { try { // 调用目标类的setter函数 m.invoke(obj, object); return true; } catch (Exception ex) { System.out.println("invoke getter on " + property + " error: " + ex.toString()); return false; } } return false; } /** * * @desc 调用set方法 */ public Object getMethodValue(String property) { Object value=null; Method m = getMethods.get(property.toLowerCase()); if (m != null) { try { /** * 调用obj类的setter函数 */ value=m.invoke(obj, new Object[] {}); } catch (Exception ex) { System.out.println("invoke getter on " + property + " error: " + ex.toString()); } } return value; } }
再一个:
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; public class ClassReflectUtil { /** * 根据类名反射创建对象 * @param name 类名 * @return 对象 * @throws Exception */ public static Object getInstance(String name) throws Exception { Class<?> cls = Class.forName(name); return cls.newInstance(); } /** * 反射方法,打印对象的属性,方法,构造器属性 * @param obj 被反射对象 */ public static void reflect(Object obj) { Class<?> cls = obj.getClass(); System.out.println("************构 造 器************"); Constructor<?>[] constructors = cls.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println("构造器名称:" + constructor.getName() + "\t"+ " " + "构造器参数类型:" + Arrays.toString(constructor.getParameterTypes())); } System.out.println("************属 性************"); Field[] fields = cls.getDeclaredFields(); // cls.getFields() 该方法只能访问共有的属性 // cls.getDeclaredFields() 可以访问私有属性 for (Field field : fields) { System.out.println("属性名称:" + field.getName() + "\t"+ "属性类型:" + field.getType()+"\t"); } System.out.println("************方 法************"); Method[] methods = cls.getMethods(); for (Method method : methods) { System.out.println("方法名:" + method.getName() + "\t" + "方法返回类型:" + method.getReturnType() + "\t"+ "方法参数类型:" + Arrays.toString(method.getParameterTypes())); } } /** * * @param obj 访问对象 * @param filedname 对象的属性 * @return 返回对象的属性值 * @throws Exception */ public static Object getFieldValue(Object obj,String filedname) throws Exception{ //反射出类型 Class<?> cls = obj.getClass(); Field field = null; //反射出类型字段 try { field = cls.getDeclaredField(filedname); } catch (Exception e) { e.printStackTrace(); System.out.println("没有这个字段:"+filedname); } //获取属性时,压制Java对访问修饰符的检查 field.setAccessible(true); //在对象obj上读取field属性的值 Object val = field.get(obj); return val; } /** * * @param obj 访问对象 * @param filedname 对象的属性 * @return 返回对象的属性值 * @throws Exception */ public static Object setIdKeyValue(Object obj,String filedname,String value) throws Exception{ //反射出类型 Class<?> cls = obj.getClass(); Field field = null; //反射出类型字段 try { field = cls.getDeclaredField(filedname); } catch (Exception e) { e.printStackTrace(); System.out.println("没有这个字段:"+filedname); } if(field==null){ return null; } //获取属性时,压制Java对访问修饰符的检查 field.setAccessible(true); //--------------------------------------------------- //针对表主键为字符类型进行赋值UUID,如果为int类型采用自增方式 if(!field.getType().getName().contains("Integer")){ field.set(obj, value); } //--------------------------------------------------- //在对象obj上读取field属性的值 Object val = field.get(obj); field.setAccessible(false); return val; } /** * * @param obj 访问对象 * @param filedname 对象的属性 * @return 返回对象的属性值 * @throws Exception */ public static Object setFieldValue(Object obj,String filedname,String value) throws Exception{ //反射出类型 Class<?> cls = obj.getClass(); Field field = null; //反射出类型字段 try { field = cls.getDeclaredField(filedname); } catch (Exception e) { e.printStackTrace(); System.out.println("没有这个字段:"+filedname); } if(field==null){ return null; } //获取属性时,压制Java对访问修饰符的检查 field.setAccessible(true); //在对象obj上读取field属性的值 Object val = field.get(obj); field.setAccessible(false); return val; } /** * 反射调用对象的方法 * @param obj 对象 * @param methodName 方法名称 * @param paramType 参数类型 new Class[]{int.class,double.class} * @param params 参数值 new Object[]{2,3.5} * @return * @throws Exception */ public static Object readObjMethod(Object obj,String methodName,Class<?>[] paramTypes,Object[] params) throws Exception{ //发现类型 Class<?> cls = obj.getClass(); //发现方法 Method method = cls.getDeclaredMethod(methodName, paramTypes); //访问方法时,压制Java对访问修饰符的检查 method.setAccessible(true); Object val = method.invoke(obj, params); return val; } public static void main(String[] args) { person p = new person(); p.setName("12"); try { System.out.println(setFieldValue(p,"names","100")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class person{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }