美文网首页JavaWeb
JavaWeb ——反射

JavaWeb ——反射

作者: 定格r | 来源:发表于2019-05-15 22:15 被阅读0次

    1.反射:框架的设计的灵魂

    框架:半成品软件。

    可以在框架的基础上进行软件开发,简化代码

    反射:将类的各个组成部分封装为其他对象,这就是反射机制

    • 好处:
      1.在运行过程中,操作 Class 里面的对象
      2.可以解耦,可以提高程序的可扩展性

    java 代码在计算机中经历的三个阶段

    image.png

    源代码阶段:字节码文件
    类对象阶段:把字节码文件加载进内存

    2.Class 对象功能:

    获取Class对象的方式:

    1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
      多用于配置文件,将类名定义在配置文件中,读取文件,加载类
     Class cls1 = Class.forName("cn.itcast.domain.Person");
    
    1. 类名.class:通过类名的属性class获取
      多用于参数的传递
    Class cls2 = Person.class;
    
    1. 对象.getClass():getClass()方法在Object类中定义着。
      多用于获取对象的字节码方式
    Person p = new Person();
    Class cls3 = p.getClass();
    

    结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的 Class 对象都是同一个

    获取功能:

    1.获取成员变量们

    - Field [] getFields(): 获取所有的 public 修饰的成员变量
    - Field [] getFields( String name):获取指定名称的 public 修饰的成员变量
    - 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()
    

    详解:

    1.Field 成员变量

    操作:

    1.设置值

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

    2.获取值

     Field a = personClass.getField("a");
            //获取成员变量a 的值
      Person p = new Person();
      Object value = a.get(p);
      System.out.println(value);
    

    3.忽略访问权限修饰符的安全检查

      Field d = personClass.getDeclaredField("d");
            //忽略访问权限修饰符的安全检查
      d.setAccessible(true);//暴力反射
      Object value2 = d.get(p);
      System.out.println(value2);
    
    2.构造方法

    1.获取构造函数

    Constructor constructor = personClass.getConstructor(String.class, int.class);
    System.out.println(constructor);
    
    // 结果:public cn.itcast.domain.Person(java.lang.String,int)
    
    Constructor constructor1 = personClass.getConstructor();
    System.out.println(constructor1);
    
    // 结果:public cn.itcast.domain.Person()
    

    2.给构造函数设置值

    Object person = constructor.newInstance("张三", 23);
    System.out.println(person);
    
    //结果:Person{name='张三', age=23, a='null', b='null', c='null', d='null'}
    

    3.创建对象

    Object person1 = constructor1.newInstance();
    System.out.println(person1);
    
    //结果:Person{name='null', age=0, a='null', b='null', c='null', d='null'}
    
    3.成员方法

    获取指定名称的方法

    //获取指定名称的方法
            Method eat_method = personClass.getMethod("eat");
            Person p = new Person();
            //执行方法
            eat_method.invoke(p);
    //结果:eat...
    

    获取重载的方法 eat

     Method eat_method1 = personClass.getMethod("eat", String.class);
     eat_method1.invoke(p, "food");
    //结果:eat...food
    
    4..获取类名
    String className = personClass.getName();
     System.out.println(className);
    //结果:cn.itcast.domain.Person
    

    3.反射小案例

    可以创建任意类的对象,可以执行任意类的方法
    1.创建 file 文件 pro.properties

    className=cn.itcast.domain.Person
    methodName=eat
    

    2.Refletest.java

        //加载配置文件
            //创建 Properties 对象
            Properties pro = new Properties();
            //加载配置文件,转换为一个集合
            ClassLoader classLoader = Refletest.class.getClassLoader();
            //获取 class 目录下的配置文件
            InputStream is = classLoader.getResourceAsStream("pro.properties");
            pro.load(is);
    
        //获取配置文件中定义的数据
            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);
    

    结果:

    image.png

    更改 pro.properties 为:

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

    结果:

    image.png

    总结:要执行某个类的某个方法,只需要更改 配置文件 pro.properties 即可

    相关文章

      网友评论

        本文标题:JavaWeb ——反射

        本文链接:https://www.haomeiwen.com/subject/gjvmaqtx.html