• Java反射


    目录

    什么是反射?

    反射我们要学习什么?

    获取class对象的三种方式

    获取构造器

    获取成员变量

    获取类方法

    反射的作用:

    反射的应用:


    什么是反射?

    java反射通俗来讲就是解剖类,并允许以编程的方式解剖类中的各个成分(构造器,成员变量,方法)。

    反射我们要学习什么?

    获取类的信息,并操作他们

    第一步:加载类,获取类的字节码:Class对象

    第二步:获取类的构造器:Constructor对象

    第三步:获取类的成员变量:Field对象

    第四步:获取类的成员方法:Method对象

    获取class对象的三种方式

    • 类名.class
    • 调用class提供方法:public static class forName(String package); //package为全类名
    • Object提供的方法:public Class getClass(); Class c = 对象.getClass();
    1. public static void main(String[] args) throws Exception {
    2. Student stu = new Student();
    3. //第一种方式,类名.的方式
    4. Class studentClass = Student.class;
    5. //通过类对象,获得类名
    6. String simpleName = studentClass.getSimpleName();
    7. //通过类对象,获取全类名
    8. String name = studentClass.getName();
    9. //第二种方式,调用Class提供的方法
    10. Class studentClass2 = Class.forName("com.example.com.yunlong.test4.Student");
    11. //第三种方式,Object提供的方法:public Class getClass();
    12. Class studentClass3 = stu.getClass();
    13. }

    获取构造器

    第一步:获取class对象

    第二步:通过 Class 对象,我们可以获取构造器信息。

    • getConstructors():获取全部的公共构造器。
    • getDeclaredConstructors():获取全部的构造器,包括私有的。
    • getConstructor(Class... parameterTypes):获取指定参数类型的公共构造器。
    • getDeclaredConstructor(Class... parameterTypes):获取指定参数类型的所有构造器,包括私有构造器。

    获取成员变量

    第一步:获取class对象

    第二步:通过 Class 对象,我们可以获取成员变量信息。

    • getFields():获取全部的公共字段。
    • getDeclaredFields():获取全部的字段,包括私有的。
    • getField(String name):获取指定名称的公共字段。
    • getDeclaredField(String name):获取指定名称的所有字段,包括私有字段。
    1. import java.lang.reflect.Field;
    2. class MyClass {
    3. public String publicField;
    4. private int privateField;
    5. public MyClass(String publicField, int privateField) {
    6. this.publicField = publicField;
    7. this.privateField = privateField;
    8. }
    9. }
    10. public class Main {
    11. public static void main(String[] args) throws Exception {
    12. // 创建 MyClass 类的实例
    13. MyClass obj = new MyClass("publicValue", 123);
    14. // 获取 MyClass 类的 Class 对象
    15. Class clazz = MyClass.class;
    16. // 获取指定名称的公共字段
    17. Field publicField = clazz.getField("publicField");
    18. // 获取指定名称的所有字段,包括私有字段
    19. Field privateField = clazz.getDeclaredField("privateField");
    20. // 设置字段的可访问性,以便访问私有字段
    21. privateField.setAccessible(true);
    22. // 获取字段的值
    23. Object publicValue = publicField.get(obj);
    24. Object privateValue = privateField.get(obj);
    25. // 输出字段的值
    26. System.out.println("Public Field Value: " + publicValue);
    27. System.out.println("Private Field Value: " + privateValue);
    28. }
    29. }

    获取类方法

    第一步:获取class对象

    第二步:通过 Class 对象,我们可以获取类中方法信息。

    • getMethods():获取类的全部公共方法。
    • getDeclaredMethods():获取类的全部方法,包括私有。
    • getMethod(String name, Class... parameterTypes):获取指定名称和参数类型的公共方法。
    • getDeclaredMethod(String name, Class... parameterTypes):获取指定名称和参数类型的所有方法,包括私有方法。
    1. import java.lang.reflect.Method;
    2. class MyClass {
    3. public void publicMethod(String param1, int param2) {
    4. System.out.println("Public Method: " + param1 + ", " + param2);
    5. }
    6. private void privateMethod() {
    7. System.out.println("Private Method");
    8. }
    9. }
    10. public class Main {
    11. public static void main(String[] args) throws Exception {
    12. // 创建 MyClass 类的实例
    13. MyClass obj = new MyClass();
    14. // 获取 MyClass 类的 Class 对象
    15. Class clazz = MyClass.class;
    16. // 获取指定名称和参数类型的公共方法
    17. Method publicMethod = clazz.getMethod("publicMethod", String.class, int.class);
    18. // 获取指定名称和参数类型的所有方法,包括私有方法
    19. Method privateMethod = clazz.getDeclaredMethod("privateMethod");
    20. // 设置私有方法可访问
    21. privateMethod.setAccessible(true);
    22. // 调用公共方法
    23. publicMethod.invoke(obj, "param1", 123);
    24. // 调用私有方法
    25. privateMethod.invoke(obj);
    26. }
    27. }

    反射的作用:

    基本作用:可以得到一个类的全部成分然后操作。

    可以破坏封装性:因为它可以访问和操作类的私有成员,而不受java语言访问修饰符的限制

    最重要的用途:适合做java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。

    反射的应用:

    Java 反射广泛应用于以下几个领域:

    1. 框架开发:许多框架使用反射来实现自动配置和扩展点的加载,比如 Spring 框架。
    2. 动态代理:通过反射可以动态地创建代理对象,实现 AOP(面向切面编程)等功能。
    3. 工具类编写:比如 ORM(对象关系映射)框架需要通过反射获取实体类的信息。
    4. 调试和诊断工具:通过反射可以查看类的结构信息,帮助调试和诊断问题。

    实例

    使用反射做一个简易版的框架

    需求:对于任意一个对象,该框架都可以把对象的字段名和对应的值,保存到文件中去。

    1. public class MyFrame {
    2. public static void saveObject(Object obj) throws Exception {
    3. PrintStream ps = new PrintStream(new FileOutputStream("E:\\workspacelong\\Thred\\src\\data.txt",true));
    4. //第一步,拿到class对象
    5. Class a = obj.getClass();
    6. String simpleName = a.getSimpleName();//拿到类名
    7. ps.println("------------"+simpleName+"-------------");
    8. //第二步,拿到类中成员变量
    9. Field[] declaredFields = a.getDeclaredFields();
    10. for (Field declaredField : declaredFields) {
    11. declaredField.setAccessible(true);
    12. //第三步,拿到成员变量的名字
    13. String name = declaredField.getName();
    14. //第四步,拿到成员变量的值,转化为String
    15. String value = declaredField.get(obj)+"";
    16. ps.println(name+"="+value);
    17. }
    18. ps.close();
    19. }
    20. }

    Java 反射的优缺点

    尽管 Java 反射提供了强大的功能,但也存在一些优缺点:

    优点:

    • 提供了灵活性和动态性,使得编程更加灵活和易扩展。
    • 可以在运行时获取类的信息,使得一些框架和工具的开发更加简便。

    缺点:

    • 性能开销较大,因为反射操作是在运行时进行的,而不是编译时。
    • 降低了代码的可读性和可维护性,因为反射使得代码更加动态和难以理解。
  • 相关阅读:
    Feign
    Java之SPI
    03142《互联⽹及其应⽤》各章简答题解答(课后习题)
    WSL增加独立的虚拟磁盘VHDX
    【原创】浅谈EtherCAT主站EOE(上)-EOE网络
    Astro是2023年最好的web框架,原因如下
    [Docker]三.Docker 部署nginx,以及映射端口,挂载数据卷
    孙哥Spring源码第21集
    Redisson--最好用的Redis客户端--介绍
    SpringBoot使用LogAspect的切面日志
  • 原文地址:https://blog.csdn.net/2401_83045332/article/details/138198952