package com.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* 这个工具类作为反射技术的工具类
* 实现包括方法的调用 属性值的设置和属性值得取出 以及
* 的到方法等功能 获取父类泛型等
* @author Administrator
*
*/
public class ReflectUtils {
/**
* 通过传入参数类的Class对象和索引
* 得到对应父类的泛型
* @param clazz获取泛型类的子类Class对象
* @param index 对于多个泛型中的哪一个泛型 即泛型索引
* @return
*/
public static Class getGernricType(Class clazz ,int index){
//得到带泛型的父类
Type type=clazz.getGenericSuperclass();
//判断得到的类是否为空
if(!(type!=null&&type instanceof ParameterizedType)){
return Object.class;
}
//得到泛型数组
//先强转为参数类型ParameterizedType 才能使用
//ParameterizedType是type的子接口 表示参数类型 Type表示的所有类型
ParameterizedType pt=(ParameterizedType) type;
Type[] types=pt.getActualTypeArguments();
//判断数组
//如果是null或者没有 返回Object.class 因为Object 是所有类的父类
if(types==null||types.length-1<index||index<0){
return Object.class;
}
//判断是否是Class 对象
if(!(types[index] instanceof Class)){
return Object.class;
}
return (Class) types[index];
}
/**
* 这个方法的功能 是实现给指定属性赋值
* @param clazz 类的Class对象
* @param fieldName 属性名称
* @param obj 这个属性所在类的对象
* @param value 给属性药赋的值
* @throws Exception
*/
public static void setFieldValue(Class clazz,String fieldName,
Object obj,Object value) throws Exception{
Field fie=getField(clazz, fieldName);
//使用暴力反射的可以实现对private的操作
fie.setAccessible(true);
fie.set(obj, value);
}
/**
*这个方法的功能是得到某个对象的指定属性的值
* @param clazz Class 对象
* @param fieldName 属性名称
* @param obj 属性对应的对象
* @return
* @throws Exception
*/
public static Object getFieldValue(Class clazz,String fieldName,Object obj) throws Exception{
Field fie=getField(clazz, fieldName);
fie.setAccessible(true);
return fie.get(obj);
}
/**
* 这个方法到的功能主要是为实现传入 类Class 对象
* 和属性值最后得到该属性
* @param clazz 类的class对象
* @param fieldName 属性名称
* @return
*/
public static Field getField(Class clazz,String fieldName) {
for(Class clazz2=clazz; clazz2!=Object.class;clazz2=clazz.getSuperclass()){
try {
Field field=clazz2.getDeclaredField(fieldName);
return field;
} catch (Exception e) {}
}
return null;
}
/**
* 这个方法的功能是调用指定的方法 如
* invoke("com.object.Student", "supperShow",33);
* @param className 类名
* @param methodName 方法名称
* @param args 调用方法要传入的参数
* @throws Exception
*/
public static void invoke(String className,String methodName,
Object ... args) throws Exception{
//得到这个类的管理对象Class 对象
Class clazz=Class.forName(className);
//得到参数的class 对象
Class[] parameterTypes = getParametrTypes(args);
/*
*适用说明: 对应下面这部分的代码可以看出他可以得到当前类的包括
*private的方法但是不能得到包括父类private在内的方法所以也就无法执行
*其父类的方法
* //得到方法
Method method=clazz.getDeclaredMethod(methodName, parameterTypes);
*/
//使用万能的获取工具的方法得到想要的对象
Method method=getMethod(clazz, methodName, parameterTypes);
//为了是private的方法也能执行 使用暴力反射
method.setAccessible(true);
//创建对象
Object obj=clazz.newInstance();
//执行方法
method.invoke(obj, args);
}
/**这个方法的就是服务于上面的invoke方法通过传入方法所需的参数
* 分别返回这些参数数的参数类型 如 int.class 等
* 获取参数类型Class对象的方法
* @param args 方法需要的参数具体的值
* @return
*/
private static Class[] getParametrTypes(Object... args) {
Class[] parameterTypes=new Class[args.length];
//遍历取到class对象
for(int i=0;i<args.length;i++){
parameterTypes[i]=args[i].getClass();
}
return parameterTypes;
}
/**
* 这个方法是返回指定方法的Method对象
* @param clazz 方法所在的类Class 对象
* @param methodName 方法名称
* @param parameterTypes 参数类型 如 int.class 等
* @return method对象
*/
public static Method getMethod(Class clazz,String methodName,
Class ... parameterTypes){
//使用循环进行遍历查找 条件就是不为Object 的Class 对 实际就是不超出
//父类的范围
for(;clazz!=Object.class;clazz=clazz.getSuperclass()){
try {
Method me=clazz.getDeclaredMethod(methodName, parameterTypes);
return me;
} catch (Exception e) {
//throw new RuntimeException(e); 这里的异常不做处理
//否则一旦第一次被捕捉后面无法在执行对于父类的方法就无法找到
}
}
return null;
}
}
|
|