A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wst123 初级黑马   /  2014-10-26 21:47  /  833 人查看  /  1 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

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


1 个回复

倒序浏览
明天看看
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马