• 反射知识


    • 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
    • 反射:将类的各个组成部分封装为其他对象,这就是反射机制

    反射的好处

    1. 可以在程序运行过程中,操作这些对象。
    2. 可以解耦,提高程序的可扩展性。

    获取Class对象的3种方式

    1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
    2. 类名.class:通过类名的属性class获取
    3. 对象.getClass():getClass()方法在Object类中定义着。
      这三种获取方式获取到的都是同一个Class对象
    package cn.itcast.reflect;
    
    import cn.itcast.domain.Person;
    import cn.itcast.domain.Student;
    
    public class ReflectDemo1 {
    
    
        /**
            获取Class对象的方式:
                1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
                2. 类名.class:通过类名的属性class获取
                3. 对象.getClass():getClass()方法在Object类中定义着。
    
         */
        public static void main(String[] args) throws Exception {
    
            //1.Class.forName("全类名")
            Class cls1 = Class.forName("cn.itcast.domain.Person");
            System.out.println(cls1);
            //2.类名.class
            Class cls2 = Person.class;
            System.out.println(cls2);
            //3.对象.getClass()
            Person p = new Person();
            Class cls3 = p.getClass();
            System.out.println(cls3);
    
            //== 比较三个对象
            System.out.println(cls1 == cls2);//true
            System.out.println(cls1 == cls3);//true
    
    
            Class c = Student.class;
            System.out.println(c == cls1);
    
    
        }
    }
    
    

    Class对象获取成员变量们

    public static void main(String[] args) throws Exception {
    
            //0.获取Person的Class对象
            Class personClass = Person.class;
            /*
                 1. 获取成员变量们
                     * Field[] getFields()
                     * Field getField(String name)
    
                     * Field[] getDeclaredFields()
                     * Field getDeclaredField(String name)
    
             */
            //1.Field[] getFields()获取所有public修饰的成员变量
            Field[] fields = personClass.getFields();
            for (Field field : fields) {
                System.out.println(field);
            }
    
            System.out.println("------------");
            //2.Field getField(String name)
            Field a = personClass.getField("a");
            //获取成员变量a 的值
            Person p = new Person();
            Object value = a.get(p);
            System.out.println(value);
            //设置a的值
            a.set(p,"张三");
            System.out.println(p);
    
            System.out.println("===================");
    
            //Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
            Field[] declaredFields = personClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println(declaredField);
            }
            //Field getDeclaredField(String name)
            Field d = personClass.getDeclaredField("d");
            //忽略访问权限修饰符的安全检查
            d.setAccessible(true);//暴力反射
            Object value2 = d.get(p);
            System.out.println(value2);
    
        }
    

    Class对象获取成员方法们

    package cn.itcast.reflect;
    
    import cn.itcast.domain.Person;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    
    public class ReflectDemo3 {
    
        /**
         Class对象功能:
             * 获取功能:
             1. 获取成员变量们
                 * Field[] getFields()
                 * Field getField(String name)
    
                 * Field[] getDeclaredFields()
                 * Field getDeclaredField(String name)
             2. 获取构造方法们
                 * Constructor<?>[] getConstructors()
                 * Constructor<T> getConstructor(类<?>... parameterTypes)
    
                 * Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
                 * Constructor<?>[] getDeclaredConstructors()
             3. 获取成员方法们:
                 * Method[] getMethods()
                 * Method getMethod(String name, 类<?>... parameterTypes)
    
                 * Method[] getDeclaredMethods()
                 * Method getDeclaredMethod(String name, 类<?>... parameterTypes)
    
             4. 获取类名
                 * String getName()
    
    
    
         */
    
        public static void main(String[] args) throws Exception {
    
            //0.获取Person的Class对象
            Class personClass = Person.class;
            /*
                2. 获取构造方法们
                     * Constructor<?>[] getConstructors()
                     * Constructor<T> getConstructor(类<?>... parameterTypes)
    
                     * Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
                     * Constructor<?>[] getDeclaredConstructors()
             */
    
    
            //Constructor<T> getConstructor(类<?>... parameterTypes)
            //有参数构造
            Constructor constructor = personClass.getConstructor(String.class, int.class);
            System.out.println(constructor);
            //创建对象
            Object person = constructor.newInstance("张三", 23);
            System.out.println(person);
    
            System.out.println("----------");
    
    
            //无参构造
            Constructor constructor1 = personClass.getConstructor();
            System.out.println(constructor1);
            //创建对象
            Object person1 = constructor1.newInstance();
            System.out.println(person1);
    
            Object o = personClass.newInstance();
            System.out.println(o);
    
    
            //constructor1.setAccessible(true);
        }
    
    
    }
    
    

    Class对象获取成员方法们

    package cn.itcast.reflect;
    
    import cn.itcast.domain.Person;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    public class ReflectDemo4 {
    
        /**
         Class对象功能:
             * 获取功能:
             1. 获取成员变量们
                 * Field[] getFields()
                 * Field getField(String name)
    
                 * Field[] getDeclaredFields()
                 * Field getDeclaredField(String name)
             2. 获取构造方法们
                 * Constructor<?>[] getConstructors()
                 * Constructor<T> getConstructor(类<?>... parameterTypes)
    
                 * Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
                 * Constructor<?>[] getDeclaredConstructors()
             3. 获取成员方法们:
                 * Method[] getMethods()
                 * Method getMethod(String name, 类<?>... parameterTypes)
    
                 * Method[] getDeclaredMethods()
                 * Method getDeclaredMethod(String name, 类<?>... parameterTypes)
    
             4. 获取类名
                 * String getName()
    
    
    
         */
    
        public static void main(String[] args) throws Exception {
    
            //0.获取Person的Class对象
            Class personClass = Person.class;
            /*
              3. 获取成员方法们:
                 * Method[] getMethods()
                 * Method getMethod(String name, 类<?>... parameterTypes)
    
                 * Method[] getDeclaredMethods()
                 * Method getDeclaredMethod(String name, 类<?>... parameterTypes)
             */
            //获取指定名称的方法,没有参数的成员方法
            Method eat_method = personClass.getMethod("eat");
            Person p = new Person();
            //执行方法
            eat_method.invoke(p);
    
            // 获取有参的成员方法
            Method eat_method2 = personClass.getMethod("eat", String.class);
            //执行方法
            eat_method2.invoke(p,"饭");
    
            System.out.println("-----------------");
    
            //获取所有public修饰的方法
            Method[] methods = personClass.getMethods();
            for (Method method : methods) {
                System.out.println(method);
                String name = method.getName();
                System.out.println(name);
                //method.setAccessible(true);
            }
    
            //获取类名
            String className = personClass.getName();
            System.out.println(className);//cn.itcast.domain.Person
    
        }
    
    
    }
    
    

    反射综合练习

    • 案例:
      * 需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
      * 实现:
      1. 配置文件
      2. 反射
      * 步骤:
      1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
      2. 在程序中加载读取配置文件
      3. 使用反射技术来加载类文件进内存
      4. 创建对象
      5. 执行方法

    1 创建一个配置文件

    配置文件里有配置全类名,和方法

    className=cn.itcast.domain.Student
    methodName=sleep
    

    2 主代码

    package cn.itcast.reflect;
    
    import cn.itcast.domain.Person;
    import cn.itcast.domain.Student;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    /**
     * 框架类
     */
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
            //可以创建任意类的对象,可以执行任意方法
    
            /*
                前提:不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法
             */
          /*  Person p = new Person();
            p.eat();*/
    /*
            Student stu = new Student();
            stu.sleep();*/
    
            //1.加载配置文件
            //1.1创建Properties对象
            Properties pro = new Properties();
            //1.2加载配置文件,转换为一个集合
            //1.2.1获取class目录下的配置文件
            ClassLoader classLoader = ReflectTest.class.getClassLoader();
            InputStream is = classLoader.getResourceAsStream("pro.properties");
            pro.load(is);
    
            //2.获取配置文件中定义的数据
            String className = pro.getProperty("className");
            String methodName = pro.getProperty("methodName");
    
    
            //3.加载该类进内存
            Class cls = Class.forName(className);
            //4.创建对象
            Object obj = cls.newInstance();
            //5.获取方法对象
            Method method = cls.getMethod(methodName);
            //6.执行方法
            method.invoke(obj);
    
    
        }
    }
    
    
  • 相关阅读:
    react 调用webIm
    css样式问题解决
    学习animejs
    vue,在模块中动态添加dom节点,并监听
    vue 关于solt得用法
    vue-cli 安装过程出现错误
    处理参数中存在多个连续空格,只显示一个空格,复制后搜索不到得问题
    http StatusCode(状态码)
    修改表单小技巧
    关于swiper中包含表单元素的bug
  • 原文地址:https://www.cnblogs.com/hellosiyu/p/12490940.html
Copyright © 2020-2023  润新知