java中的反射机制

java中的反射机制

1.类加载器:ClassLoader

1580977084726

​ Class.forName(“全类名”) 类名.Class 对象.getClass()

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

  • 好处:

    1. 可以在程序运行过程中,操作这些对象

    2. 可以解耦,提高程序的可扩展性。

  • 获取Class对象的方式:

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

      • 多用于对象的获取字节码的方式

2.结论:

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

Class对象都是同一个。

3.Class对象的功能:

  • 获取功能:

    1. 获取成员变量们

      • Field[] getFields():获取所有 public修饰的成员变量

      • Field getField(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()
  • Field:成员变量

    • 操作:
      1. 设置值
        • void set(Object obj,Object value)
      2. 获取值
        • get(Object obj)
      3. 忽略访问权限修饰符的安全检查
        • setAccessible(true);//暴力反射
  • Constructor:构造方法

    • 创建对象:
      • T newInstance(Object… initargs)
      • 如何使用空参构造方法创建对象,操作可以简化 :Class对象的newInstance方法
  • Method:方法对象

    • 执行方法:
      • Object invoke(Object obj,object… args)
    • 获取方法名称:
      • String getName 获取方法名

4.案例:

  • 需求:写一个”框架“,不能改变该类的任何代码的前提下,可以帮助我们创建任意类的对象,并且执行其中任意方法

    • 实现:

      1. 配置文件

      2. 反射

    • 步骤:

      1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
      2. 在程序中加载读取配置文件

​ 3. 使用反射技术来加载类文件进内存

  1. 创建对象

    1. 执行方法

      实现的方法:(ReflectTest.java)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //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);
  • 配置文件:(pro.properties)
1
2
className=tree.Student
methodName=sleep