• Java中的反射


    反射:框架设计的灵魂
      框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
      反射:将类的各个组成部分封装为其他对象,这就是反射机制
      好处:
        1. 可以在程序运行过程中,操作这些对象。
        2. 可以解耦,提高程序的可扩展性。

      获取Class对象的方式:
        1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
          多用于配置文件,将类名定义在配置文件中。读取文件,加载类
        2. 类名.class:通过类名的属性class获取
          多用于参数的传递
        3. 对象.getClass():getClass()方法在Object类中定义的。
          多用于对象的获取字节码的方式

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

    Class对象的方法:
      获取方法:
        1. 获取成员变量们
          Field[] getFields() :获取所有public修饰的成员变量
          Field getField(String name) 获取指定名称的 public修饰的成员变量

          Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
          Field getDeclaredField(String name)
        2. 获取构造方法们
          Constructor<?>[] getConstructors()
          Constructor<T> getConstructor(类<?>... parameterTypes)

          Constructor<?>[] getDeclaredConstructors()

          Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  

        3. 获取成员方法们:
          Method[] getMethods()
          Method getMethod(String name, 类<?>... parameterTypes)

          Method[] getDeclaredMethods()
          Method getDeclaredMethod(String name, 类<?>... parameterTypes)

        4. 获取全类名
          String getName()

    Field:成员变量
      操作:
        1. 设置值
          void set(Object obj, Object value)
        2. 获取值
          get(Object obj)

        3. 忽略访问权限修饰符的安全检查
          setAccessible(true):暴力反射

    Constructor:构造方法
      创建对象:
        T newInstance(Object... initargs)

        如果使用空参数构造方法创建对象,操作可以简化,不需要获取空参构造方法,直接使用:Class对象.newInstance();

       忽略访问权限修饰符的安全检查
        setAccessible(true):暴力反射

    Method:方法对象
      执行方法:
        Object invoke(Object obj, Object... args)

      获取方法名称:
        String getName:获取方法名

      忽略访问权限修饰符的安全检查
        setAccessible(true):暴力反射

    模拟框架解耦程序,要改动的代码用配置文件配置起来:

    package com.fgy.domain;
    
    public class Person {
        public void sleep() {
            System.out.println("sleep...");
        }
    }
    package com.fgy.domain;
    
    public class Student {
        public void eat() {
            System.out.println("eat...");
        }
    }

    配置文件:

      className = com.fgy.domain.Person

      methodName = sleep

    package com.fgy.reflect;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.Method;
    import java.net.URL;
    import java.util.Properties;
    import java.util.Set;
    
    /**
     * 模拟框架类
     */
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
            // 1.加载配置文件
            Properties pro = new Properties();
            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 cla = Class.forName(className);
    
            // 4.创建对象
            Object obj = cla.newInstance();
    
            // 5.获取方法对象
            Method method = cla.getMethod(methodName);
    
            // 6.执行方法
            method.invoke(obj);
        }
    }
  • 相关阅读:
    Shell脚本 --- 正则表达式和文本处理工具
    python的eval、exec函数
    内置函数 Built-in Functions
    关于Python中的lambda
    Python中*args和**kwargs的区别
    Python基础-10-文件操作
    Python基础-09-内置函数
    Python基础-08-函数
    Python基础-07-集合
    Python基础-06-字典
  • 原文地址:https://www.cnblogs.com/roadlandscape/p/12180889.html
Copyright © 2020-2023  润新知