反射小工具

来源:互联网 发布:金融数据 驾驶仓 编辑:程序博客网 时间:2024/06/06 13:19
package alone.utils.reflect;import java.beans.PropertyDescriptor;import java.lang.reflect.*;/** * 反射 : 在 运行时 [ 创建任意类对象,操作任意对象的属性,调用任意类对象的方法]。 * 反射工具类,针对反射的一些操作,整理合并 * @author alone_xuxu 2017年7月6日 上午9:31:18 */public final class ReflectionUtils{/** * 将反射中常见的几种异常进行处理,抛出.以使的我们的这个小工具类开起来更加简洁 * @param exception  遇到的异常 * @return * @author alone_xuxu 2017年7月6日 上午10:58:03 */public static IllegalArgumentException convertException(Exception exception) {if (exception instanceof IllegalAccessException|| exception instanceof SecurityException|| exception instanceof NoSuchFieldException) {throw new IllegalArgumentException("反射操作时遇到了异常: " + exception);}throw new IllegalArgumentException(exception);}/** * 为属性赋值操作,通过属性的  setter 方法 *  * @author alone_xuxu 2017年7月6日 上午9:33:37 */public static <T>  void  setPropertyValue(T t,String propertyName,Object value){//获取泛型类型Class<?> beanClass = t.getClass();try {//获取这个属性的属性描述器PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, beanClass);//获取这个属性的写入方法Method  writeMethod = propertyDescriptor.getWriteMethod();//开始写入操作writeMethod.invoke(t, value);} catch (Exception e) {convertException(e);}}/** * 获取属性值,通过属性的geter 方法获取 *  * @author alone_xuxu 2017年7月6日 上午9:34:24 */public static <T> Object getPropertyValue(T t, String propertyName) {// 获取泛型类型Class<?> beanClass = t.getClass();try {// 获取这个属性的属性描述器PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, beanClass);// 获取这个属性值的获取方法Method readMethod = propertyDescriptor.getReadMethod();// 开始读取操作Object obj = readMethod.invoke(t);if (obj != null)return obj;} catch (Exception e) {convertException(e);}return null;}/** * 通过 操作的对象,对象的属性名,设置该属性值的属性值,直接操作属性的方式完成的 * @param t 哪一个对象 * @param fieldName  哪一个属性名 * @param value     设置个什么值 * @author alone_xuxu 2017年7月6日 上午10:02:07 */public static <T>  void  setFieldValue(T t,String fieldName,Object value){Class<?> clazz = t.getClass();Field field = null;try {field = clazz.getDeclaredField(fieldName);if(field == null) throw new RuntimeException("反射操作异常");//设置越过访问权限field.setAccessible(true);//开始设置属性值field.set(t,value);} catch (Exception e) {convertException(e);}}/** * 通过 操作的对象,对象的属性名,获取属性值,直接操作属性的方式完成的 * @param t  哪个对象 * @param fieldName  哪个属性 * @return  返回的是这个属性的 值,如果么有就返回 null * @author alone_xuxu 2017年7月6日 上午10:00:22 */public static <T> Object getFieldValue(T t, String fieldName) {try {//我们应该在当前类,及当前类所有的父类中开始查找操作Field field = getDeclaredField(t, fieldName);//field = clazz.getDeclaredField(fieldName);//这里找不着的话,那就是么有了if (field == null)throw new RuntimeException("反射操作异常");// 设置越过访问权限field.setAccessible(true);// 开始获取属性值return field.get(t);} catch (Exception e) {convertException(e);}return null;}/** * 获取一个类中的一个属性 * @param t   哪一个类 * @param fieldName哪一个属性 * @return返回找到的属性 * @author alone_xuxu 2017年7月6日 上午10:49:45 */private static <T> Field getDeclaredField(T t, String fieldName) {Field field = null;Class<?> superClass  = t.getClass();//一直找到Object 中,如果找不到,那就是找不着了,如果找到,进行操作while(superClass != Object.class){try{field = superClass.getDeclaredField(fieldName);if(field != null) break;}catch(Exception e){//异常不管,暂时不处理,暂时处理不了}superClass = superClass.getSuperclass();}return field;}/** * 通过反射执行调用一个方法 * @param object   哪一个对象的方法 * @param methodName  哪一个方法 * @param parameterTypes  参数列表的所有类型 * @param params参数列表 * @author alone_xuxu 2017年7月6日 上午10:11:40 * @return  返回的是,我们执行这个方法之后返回的结果 */public static Object invokeMethod(Object object, String methodName,Class<?>[] parameterTypes, Object[] params) {// 获取到这个方法// 1. 获取这个对象的类型,通过这个类型来获取这个方法,如果有这个方法,我们将可以操作这个方法Class<?> superClass = object.getClass();try {// 获取所有这个有关的方法,如果当前类,找不着,就到父类中找Method method = getDeclaredMethod(methodName, parameterTypes,superClass);// 查找完毕,如果这个时候我们的method 还是空的,表示没有找到我们需要的方法if (method == null)throw new RuntimeException("没有找到合适的方法" + methodName + "在 "+ object.getClass().getCanonicalName() + "中");// 这里表示我们在找到了,我们需要开启暴力访问method.setAccessible(true);return method.invoke(object, params);} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}// 执行这个方法操作return null;}/** * 获取一个类中的一个方法,忽略这个方法的访问权限 * @param methodName   需要获取的方法的名称 * @param parameterTypes   需要被获取的方法的方法参数列表的类型 * @param superClass需要获取的类的 Class 类型 * @return返回的是我们找到的方法.找不到就返回 null * @author alone_xuxu 2017年7月6日 上午10:44:46 */private static Method getDeclaredMethod(String methodName,Class<?>[] parameterTypes, Class<?> superClass) {Method method = null;// 通过while循环实现这个操作,一直找到Object中,找不着为止,因为object// 是抽象的,里面有大量底层方法,我们程序员,不能直接操作这个,很危险while (superClass != Object.class) {try {method = superClass.getDeclaredMethod(methodName,parameterTypes);if(method != null) return method;//找着了,就直接退出去} catch (NoSuchMethodException e) {// 当前类中,没有找到,或者发生了其他的异常.我们暂时不管吧.处理不了}superClass = superClass.getSuperclass();// 向着父类开找啊}return null;}/** * 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.  * @param clazz   需要获取泛型的父类 * @param index   如果有多个,index是用来指定获取到哪一个的 * @return父类的泛型参数的类型. 如无法找到, 返回Object.class * @author alone_xuxu 2017年7月6日 上午10:44:46 */    public static Class<Object> getSuperClassGenricType(final Class clazz, final int index) {                    //返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。          Type genType = clazz.getGenericSuperclass();          if (!(genType instanceof ParameterizedType)) {           return Object.class;          }          //返回表示此类型实际类型参数的 Type 对象的数组。          Type[] params = ((ParameterizedType) genType).getActualTypeArguments();            if (index >= params.length || index < 0) {                       return Object.class;          }          if (!(params[index] instanceof Class)) {                return Object.class;          }            return (Class) params[index];      }  }