认识反射

  • 反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。

  • 反射使用过程:

    1. 反射第一步: 加载类,获取类的字节码: Class 对象
    2. 获取类的构造器: Constructor对象
    3. 获取类的成员变量: Field对象
    4. 获取类的成员方法: Method对象
  • 反射的作用:

    • 基本作用:可以得到一个类的全部成分然后操作
    • 可以破坏封装性。
    • 最重要的用途是: 适合做 Java 的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。
  • 使用场景:例如:设计一个框架。对于任意一个对象,该框架都可以把对象的字段名和对应的值,保存到文件中去。实现步骤如下:

    1. 定义一个方法,可以接收任意对象。
    2. 每收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量。
    3. 遍历成员变量,然后提取成员变量在该对象中的具体值。
    4. 把成员变量名、和其值,写出到文件中去即可。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    package com.atxiong.reflect;

    import java.io.FileOutputStream;
    import java.io.PrintStream;
    import java.lang.reflect.Field;

    /**
    *
    * @Author Xiong
    * @data 2023/8/22
    * @Description 保存任意对象的字段和数据到文件中
    */
    public class ObjectFrame {
    public static void saveObject(Object obj) throws Exception {
    PrintStream ps = new PrintStream(new FileOutputStream("./src/data.txt", true));

    //获取类
    Class c = obj.getClass();
    String cName = c.getSimpleName();
    ps.println("-----------------" + cName + "-----------------");

    //获取全部成员变量
    Field[] fields = c.getDeclaredFields();

    //遍历每个成员变量
    for (Field field : fields) {
    //拿到成员变量的名字
    String name = field.getName();
    //拿到该成员变量的数据
    field.setAccessible(true); //禁止检查访问控制
    String value = field.get(obj) + "";
    ps.println(name + "=" + value);
    }
    ps.close();
    }
    }

获取类

获取Class对象的三种方式:

  • Class c1=类名.class
  • 调用Class提供方法: public static Class forName(String package); Class c2 = Class.forName("package名字")
  • Object提供的方法: public Class getClass(); Class c3=对象.getClass();

获取类的构造器

获取类的构造器方法:

方法说明
Constructor<?>[] getConstructors()获取全部构造器(只能获取public修饰的)
Constructor<?>[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到)
Constructor<T> getConstructor(Class<?>... parameter Types)获取某个构造器(只能获取public修饰的)
Constructor<T> getDeclaredConstructor(Class<?>... parameter Types)获取某个构造器(只要存在就能拿到)

获取类构造器的作用:初始化对象返回。

Constructor提供的方法说明
T newInstance(Object... initargs)调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)

获取类的成员变量

获取类中成员变量的方法:

方法说明
public Field[] getFields()获取类的全部成员变量(只能获取public修饰的)
public Field[] getDeclaredFields()获取类的全部成员变量(只要存在就能拿到)
public Field getField(String name)获取类的某个成员变量(只能获取public修饰的)
public Field getDeclaredField(String name)获取类的某个成员变量(只要存在就能拿到)

获取成员变量的作用:赋值、取值。

方法说明
void set(Object obj, Object value)赋值
Object get(Object obj)取值
public void setAccessible(boolean flag)设置为true,表示禁止价差访问控制(暴力反射)

获取类的成员方法

获取类中成员方法的方法:

方法说明
Method[] getMethods()获取类的全部成员方法(只能获取public修饰的)
Method[] getDeclaredMethods()获取类的全部成员方法(只要存在就能拿到)
Method getMethod(String name, Class<?>... parameter Types)获取类的某个成员方法(只能获取public修饰的)
Method getDeclaredMethod(String name, Class<?>... parameter Types)获取类的某个成员方法(只要存在就能拿到)

获取类中成员方法的作用:执行该方法。

方法说明
public Object invoke(Object obj, Object... args)触发某个对象的该方法执行
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制 (暴力反射)