反射小工具

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];  
    }  

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值