学习反射

反射

一、Java的反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

二、关键点-获取Class文件对象

Properties p = new Properties();
        p.load(Test01.class.getClassLoader().getResourceAsStream("classPath.properties"));
        String path = p.getProperty("path");
        Class<?> clazz = Class.forName(path);
        
        //获取本类及其父类公有的方法对象
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        
        //获取本类所有的方法对象
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        
        //获取本类及其父类的所有对象
        for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {
            Method[] methods = c.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
        }
        
        //获取本类公有的指定名字的方法对象
        Method method = clazz.getMethod("setClassId",String.class);
        System.out.println(method);
        
        //利用反射工具类获取子类及其父类指定名字的方法对象
        Method method = ReflexUtil.getMethod(clazz, "method");
        System.out.println(method);
        
        //获取方法参数值
        int modifiers = method.getModifiers();
        System.out.println("是否使用public修饰:" + Modifier.isPublic(modifiers));
        System.out.println("是否使用static修饰:" + Modifier.isStatic(modifiers));
        System.out.println("是否使用final修饰:" + Modifier.isFinal(modifiers));
        System.out.println("是否使用private修饰:" + Modifier.isPrivate(modifiers));
        System.out.println("是否使用protected修饰:" + Modifier.isProtected(modifiers));
        System.out.println("是否使用abstract修饰:" + Modifier.isAbstract(modifiers));
        System.out.println("是否使用synchronized修饰:" + Modifier.isSynchronized(modifiers));
        
        
        
        
    }

三、利用反射操作方法

public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        
        Properties p = new Properties();
        p.load(Test01.class.getClassLoader().getResourceAsStream("classPath.properties"));
        String path = p.getProperty("path");
        Class<?> clazz = Class.forName(path);
        
        //利用反射调用静态方法
        Method method = ReflexUtil.getMethod(clazz, "method");
        method.invoke(null);//静态方法不需要对象调用,就传入null
        
        Student stu = new Student();
        
        //利用反射调用成员方法 -- 无参数无返回值的方法
        Method method01 = ReflexUtil.getMethod(clazz, "method01");
        method01.invoke(stu);
        
        //利用反射调用成员方法 -- 带参数的方法
        Method method02 = ReflexUtil.getMethod(clazz, "method02", String.class,int.class);
        method02.invoke(stu, "好好学习,天天向上",100);
        
        //利用反射调用成员方法 -- 无参数带返回值的方法
        Method method03 = ReflexUtil.getMethod(clazz, "method03");
        String returnVal1 = (String) method03.invoke(stu);
        System.out.println(returnVal1);
        
        //利用反射调用成员方法 -- 带参数带返回值的方法
        Method method04 = ReflexUtil.getMethod(clazz, "method04", String.class,int.class);
        method04.setAccessible(true);//调用私有的成员方法是需要设置修改权限
        String returnVal2 = (String)method04.invoke(stu, "好好学习,天天向上",200);
        System.out.println(returnVal2);
        
        //利用反射工具类 -- 调用静态方法
        ReflexUtil.invoke(clazz, "method", null, null);
        
        Student stu = new Student();
        //利用反射工具类 -- 反射调用成员方法 -- 无参数无返回值的方法
        ReflexUtil.invoke(stu, "method01", null, null);
        
        //利用反射工具类 -- 反射调用成员方法 -- 带参数的方法
        ReflexUtil.invoke(stu, "method02", new Class[] {String.class,int.class}, new Object[] {"好好学习,天天向上",100});
        
        //利用反射工具类 -- 反射调用成员方法 -- 无参数带返回值的方法
        Object returnVal1 = ReflexUtil.invoke(stu, "method03", null, null);
        System.out.println(returnVal1);
        
        //利用反射工具类 -- 反射调用成员方法 -- 带参数带返回值的方法
        Object returnVal2 = ReflexUtil.invoke(stu, "method04", new Class[] {String.class,int.class}, new Object[] {"好好学习,天天向上",100});
        System.out.println(returnVal2);
        
    }

四、利用反射操作方法里的参数和返回值

public static void main(String[] args) throws IOException, ClassNotFoundException {
        
        Properties p = new Properties();
        p.load(Test03.class.getClassLoader().getResourceAsStream("classPath.properties"));
        String path = p.getProperty("path");
        Class<?> clazz = Class.forName(path);
        
        //利用反射工具类获取方法对象
        Method method = ReflexUtil.getMethod(clazz, "method04", String.class,int.class);
        
        //获取方法的参数个数
        int parameterCount = method.getParameterCount();
        System.out.println("获取方法的参数个数:" + parameterCount);
        System.out.println("------------------------------------");
        
        //获取方法参数的class对象数组
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (Class<?> c : parameterTypes) {
            System.out.println(c);
        }
        System.out.println("------------------------------------");
        
        //获取方法参数的Type对象数组
        //一个参数类型就是一个Type对象
        Type[] genericParameterTypes = method.getGenericParameterTypes();
        for (Type type : genericParameterTypes) {
            System.out.println(type);
            System.out.println("------------------------------------");
        }
        
        //获取方法参数对象数组
        //一个参数就是一个参数对象
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println("获取方法的参数类型" + parameter.getType());
            
            /**
             * 注意:参数名不会随着编译而编译到class文件
             *      class文件描述该方法的参数名使用的是:arg0,arg1,arg2...
             */
            System.out.println("获取方法的参数名" + parameter.getName());
        }
        System.out.println("------------------------------------");
        
        //获取返回值的class对象
        Class<?> returnType = method.getReturnType();
        System.out.println("获取返回值的class对象:" + returnType);
        
        //获取返回值的Type对象
        Type genericReturnType = method.getGenericReturnType();
        System.out.println("获取返回值的type对象:" + genericReturnType);
        
        
    }
​
​

五、利用反射操作泛型

public static void main(String[] args) throws IOException, ClassNotFoundException {
        
        Properties p = new Properties();
        p.load(Test04.class.getClassLoader().getResourceAsStream("classPath.properties"));
        String path = p.getProperty("path");
        Class<?> clazz = Class.forName(path);
        
        //获取属性上的泛型类型
        Field field = ReflexUtil.getField(clazz, "map");
        Type fieldType = field.getGenericType();
        ParameterizedType fieldTypePT = (ParameterizedType) fieldType;
        Type[] actualTypeArguments = fieldTypePT.getActualTypeArguments();
        for (Type type : actualTypeArguments) {
            System.out.println(type);
        }
        
        System.out.println("---------------------------");
        
        Method method = ReflexUtil.getMethod(clazz, "method05", ArrayList.class,HashMap.class);
        
        //获取方法参数上的泛型类型
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            Type parameterizedType = parameter.getParameterizedType();
            ParameterizedType parameterTypePT = (ParameterizedType) parameterizedType;
            Type[] actualTypeArguments2 = parameterTypePT.getActualTypeArguments();
            for (Type type : actualTypeArguments2) {
                System.out.println(type);
            }
            
        }
        
        System.out.println("---------------------------");
        
        //获取方法上返回值的泛型类型
        Type genericReturnType = method.getGenericReturnType();
        ParameterizedType returnPT = (ParameterizedType) genericReturnType;
        Type[] actualTypeArguments2 = returnPT.getActualTypeArguments();
        for (Type type : actualTypeArguments2) {
            System.out.println(type);
        }
        }

六、利用反射操作注解

public static void main(String[] args) throws IOException, ClassNotFoundException {
        Properties p = new Properties();
        p.load(Test05.class.getClassLoader().getResourceAsStream("classPath.properties"));
        String path = p.getProperty("path");
        Class<?> clazz = Class.forName(path);
        
        //获取类上的注解信息
        MyAnnotaction classAnnotation = clazz.getAnnotation(MyAnnotaction.class);
        System.out.println(classAnnotation.str());
        
        System.out.println("--------------------");
        
        //获取属性上的注解信息
        Field field = ReflexUtil.getField(clazz, "map");
        MyAnnotaction fieldAnnotation = field.getAnnotation(MyAnnotaction.class);
        System.out.println(fieldAnnotation.str());
        
        System.out.println("--------------------");
        
        //获取方法上的注解信息
        Method method = ReflexUtil.getMethod(clazz, "method05", ArrayList.class,HashMap.class);
        MyAnnotaction methodAnnotation = method.getAnnotation(MyAnnotaction.class);
        System.out.println(methodAnnotation.str());
        
        System.out.println("--------------------");
        
        //获取参数上的注解信息
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            MyAnnotaction parameterAnnotation = parameter.getAnnotation(MyAnnotaction.class);
            if(parameterAnnotation != null) {//说明该参数上有MyAnnotaction的注解
                System.out.println(parameterAnnotation.str());
            }
            
        }
        
        
        
        
    }

七、利用反射操作数组

public static void main(String[] args) {
        
        //创建数组
        int[] arr = (int[]) Array.newInstance(int.class, 10);
        
        //获取数组长度
        int length = Array.getLength(arr);
        System.out.println("获取数组长度:" + length);
        
        //循环设置每个下标上的元素
        for (int i = 0; i < Array.getLength(arr); i++) {
            
            //设置当前下标上的元素
            Array.set(arr, i, i+1);
            
        }
        
        
        //循环设置每个下标上的元素
        for (int i = 0; i < Array.getLength(arr); i++) {
            //获取当前下标上的元素
            Object element = Array.get(arr, i);
            System.out.println(element);
        }
        
    }
​
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值