zoukankan      html  css  js  c++  java
  • Java Reflection 反射基础

    反射基础:

    package reflection;
    
    /**
     * Created by : Infaraway
     * DATE : 2017/3/2
     * Time : 23:06
     * Funtion : Person为父类
     */
    public class Person {
        public String name;
        public Integer age;
        private String address;
        private String phoneNumber;
        private String email;
    
        public Person() {
    
        }
    
        public Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        private void personMethod(){
            System.out.println("this is personMethod...");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setName(String name, Integer age){
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getPhoneNumber() {
            return phoneNumber;
        }
    
        public void setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    package reflection;
    
    /**
     * Created by : Infaraway
     * DATE : 2017/3/3
     * Time : 12:17
     * Funtion : Student子类
     */
    public class Student extends Person {
    
        public String classes;
    
        private String school;
        private String grade;
    
        public Student() {
        }
    
        public Student(String name, Integer age) {
            super(name, age);
        }
    
        private void studentMethod(String school){
            System.out.println("this is studentMethod...");
        }
    }

    最基本的反射使用为一下的代码表示:主要获取 字段 和 方法为主;

    package reflection;
    
    import org.junit.Test;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * Created by : Infaraway
     * DATE : 2017/3/2
     * Time : 23:10
     * Funtion : 反射及基本用法
     */
    public class testReflect {
    
        String className = "reflection.Student";
    
        /**
         * 测试反射的基本用法
         * @throws Exception
         */
        @Test
        public void testPerson() throws Exception {
            Class clazz = Class.forName("reflection.Person");
    
            // 1. Class类中的getFields,getMethods,getConstructors方法
            // 分别返回提供的 public  域 方法 和构造器
            // 并且包括超类的公有成员
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }
    
            Method [] methods = clazz.getMethods();
            for (Method method: methods) {
                System.out.println(method.getName());
            }
    
            Constructor [] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor.getName());
            }
    
    
            // 2. Class类中的getDeclaredFields,getDeclaredMethods,getDeclaredConstructors方法
            // 获取所有的方法包括 private方法,且只获取当前类声明的方法
            // 不包括超类的成员
            Field[] fieldsDeclared = clazz.getDeclaredFields();
            for (Field field : fieldsDeclared) {
                System.out.println(field.getName());
            }
    
    
            Method [] methodsDeclared = clazz.getDeclaredMethods();
            for (Method method: methodsDeclared) {
                System.out.println("method2---"+method.getName());
            }
    
            Constructor [] constructorsDeclared = clazz.getDeclaredConstructors();
            for (Constructor constructor : constructorsDeclared) {
                System.out.println(constructor.getName());
            }
    
    
            // 3.获取指定的方法   getDeclaredMethod可以获取私有的方法
            // 获取特定方法时,需要两个东西确定调用的方法:1)方法名,2)方法的参数(重载)
            Method methodSp = clazz.getDeclaredMethod("setName",String.class);
            System.out.println(methodSp);
    
            //当需要使用反射式,参数类型必须是包装类  int --> Integer 等等
            Method methodSp2 = clazz.getDeclaredMethod("setName",String.class, Integer.class);
            System.out.println(methodSp2);
    
            //4. 执行方法
            Object object = clazz.newInstance();
            methodSp.invoke(object, "zhong");
    
    
    
        }
    }

    也可以通过反射获取并且调用父类的方法(包括public 和private)

    以下只提供实现上述方法的工具类:

    package reflection;
    
    import java.lang.reflect.Method;
    
    /**
     * Created by : Infaraway
     * DATE : 2017/3/3
     * Time : 12:18
     * Funtion :
     */
    public class ReflectUtils {
    
        /**
         * 返回方法
         * @param clazz 类
         * @param methodName 方法名称
         * @param args   参数列表
         * @return 返回方法(由于使用了setAccessible方法,改使private的 method也可执行)
         */
        public static Method getMethod(Class clazz, String methodName, Object...args) {
            Method method = null;
            Class [] parametersTypes = new Class[args.length];
            //得到所有参数的class
            for (int i = 0; i < args.length; i++) {
                parametersTypes[i] = args[i].getClass();
            }
            for (;clazz != Object.class; clazz = clazz.getSuperclass()){
                try {
                    method = clazz.getDeclaredMethod(methodName,parametersTypes);
                    method.setAccessible(true);
                    return method;
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        /**
         * 获取clazz中的methodName方法,该方法可能是私有方法,也可能是父类中的私有方法
         * @param clazz 类
         * @param methodName 方法名称
         * @param parametersTypes 参数类型数组
         * @return 方法的对象
         */
        public static Method getSuperMehtod(Class clazz, String methodName, Class...parametersTypes){
            Method method = null;
            for (;clazz != Object.class; clazz = clazz.getSuperclass()){
                try {
                    method = clazz.getDeclaredMethod(methodName, parametersTypes);
                    return method;
                }catch (Exception e){
                   //method不在当前类定义,继续向上转型
                }
            }
            return null;
        }
    
        /**
         * 反射执行调用方法,可以使public 或者 private 可以使当前类或者 父类
         * @param obj 类对象
         * @param methodName 方法名
         * @param args  参数列表
         * @return 方法的返回值
         */
        public static Object invokeMethod(Object obj, String methodName, Object...args){
            Class [] parametersTypes = new Class[args.length];
            //得到所有参数的class
            for (int i = 0; i < args.length; i++) {
                parametersTypes[i] = args[i].getClass();
            }
    
            try {
                Method method = getSuperMehtod(obj.getClass(), methodName, parametersTypes);
                //设置私有方法可调用
                method.setAccessible(true);
                //执行method方法 并返回方法的返回值
                return method.invoke(obj, args);
            }catch (Exception e ){
                e.printStackTrace();
            }
            return null;
        }
    }

    本文所需完整版代码:https://git.oschina.net/infaraway/basisJava/tree/master/src/reflection

  • 相关阅读:
    在eclipse创建android project,最后一步点击finish没反应
    有哪些可以将网页另存图片的chrome插件?功能类似网页截图
    极品家丁—优酷全网独播喜剧
    如何安装chrome扩展?比如json-handle插件如何安装
    安装用户脚本的福音:Tampermonkey(油猴)
    多微博账号同时发微博的插件--fawave
    正能量-真正男子汉2
    如何看待优酷广告?
    秋雨连绵思晚天
    如何用Postman组装Request并且查看Response
  • 原文地址:https://www.cnblogs.com/infaraway/p/6498782.html
Copyright © 2011-2022 走看看