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];
}
}
反射小工具
最新推荐文章于 2022-07-02 17:59:21 发布