如果你用过 Spring、Hibernate 这类框架,或是写过 JDBC 连接数据库的代码,可能没直接写过 “反射” 相关逻辑,但这些工具的核心功能 —— 比如 Spring 的 IOC 容器、JDBC 加载驱动 —— 全都依赖 Java 反射机制。今天就从 “是什么、怎么用、有啥用” 三个维度,带你搞懂这个关键特性。

一、先搞懂:反射到底是什么?

Java 反射机制的核心定义很明确:在程序运行状态下,对任意一个类,能获取它的所有属性和方法;对任意一个对象,能调用它的任意方法和属性。简单说,它打破了 “编译时确定类信息” 的限制,让程序在运行时能 “动态” 操作类和对象。

而实现这一切的核心,是Class类对象 —— 它就像一个 “类的说明书”,存储了某个类的方法、变量、构造器等所有信息,程序通过它才能动态获取类的细节。

二、关键步骤:如何获取 Class 对象?

要用反射,第一步必须拿到目标类的Class对象,Java 提供了两种常用方式,适用场景不同:

  1. 已知具体类时:用.class如果提前知道要操作的类(比如TargetObject),直接通过类名加.class获取,语法简单:

    java

    运行

    Class targetClass = TargetObject.class;
    

    但这种方式局限性大,实际开发中很少用 —— 因为反射的核心场景是 “不知道具体类”(比如遍历包下的类)。

  2. 未知具体类时:用Class.forName()更常用的方式是通过 “类的全路径”(包名 + 类名)动态加载,适合不知道具体类的场景(比如框架加载配置文件中的类):

    java

    运行

    // 示例:加载cn.javaguide包下的TargetObject类
    Class targetClass = Class.forName("cn.javaguide.TargetObject");
    

三、实战演示:用反射操作类和对象

光说概念不够,我们通过一段完整代码,看反射如何 “动态” 调用方法、修改属性(以TargetObject类为操作目标)。

1. 第一步:创建目标类(被反射操作的类)

先定义一个包含私有属性、公有方法和私有方法的类,模拟真实开发中的类结构:

java

运行

package cn.javaguide;

public class TargetObject {
    // 私有属性
    private String value;

    // 无参构造器(反射创建实例会用到)
    public TargetObject() {
        value = "JavaGuide"; // 初始化私有属性
    }

    // 公有方法
    public void publicMethod(String s) {
        System.out.println("I love " + s);
    }

    // 私有方法
    private void privateMethod() {
        System.out.println("value is " + value);
    }
}
2. 第二步:用反射操作目标类

通过反射完成 “创建实例、获取方法、调用方法、修改私有属性” 四个核心操作,代码中关键步骤已加注释:

java

运行

package cn.javaguide;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws 
            ClassNotFoundException, NoSuchMethodException, 
            IllegalAccessException, InstantiationException, 
            InvocationTargetException, NoSuchFieldException {

        // 1. 加载TargetObject类,获取Class对象
        Class<?> targetClass = Class.forName("cn.javaguide.TargetObject");
        
        // 2. 通过Class对象创建TargetObject实例(需无参构造器)
        TargetObject targetObject = (TargetObject) targetClass.newInstance();

        // 3. 获取类的所有方法(包括私有方法),并打印方法名
        Method[] methods = targetClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName()); // 输出:publicMethod、privateMethod
        }

        // 4. 调用公有方法publicMethod(需指定方法名和参数类型)
        Method publicMethod = targetClass.getDeclaredMethod("publicMethod", String.class);
        publicMethod.invoke(targetObject, "JavaGuide"); // 输出:I love JavaGuide

        // 5. 修改私有属性value(私有属性需取消安全检查)
        Field valueField = targetClass.getDeclaredField("value");
        valueField.setAccessible(true); // 关闭访问检查,允许操作私有属性
        valueField.set(targetObject, "JavaGuide"); // 重新赋值

        // 6. 调用私有方法privateMethod(私有方法同样需取消安全检查)
        Method privateMethod = targetClass.getDeclaredMethod("privateMethod");
        privateMethod.setAccessible(true); // 关闭访问检查
        privateMethod.invoke(targetObject); // 输出:value is JavaGuide
    }
}
3. 最终输出结果

运行Main类后,控制台输出如下,和预期一致:

plaintext

publicMethod
privateMethod
I love JavaGuide
value is JavaGuide

四、核心对比:静态编译 vs 动态编译

反射能实现 “动态操作”,本质是因为它属于动态编译,和我们平时写的 “静态编译” 代码有根本区别:

  • 静态编译:编译时就确定类的类型、绑定对象,比如TargetObject obj = new TargetObject();,编译阶段就知道objTargetObject类型。
  • 动态编译:运行时才确定类的类型、绑定对象,比如反射通过Class.forName()加载类,运行时才知道要操作哪个类。

五、客观看待:反射的优缺点

反射不是 “万能工具”,它的优势和劣势都很明显,实际使用中需要权衡:

优点
  1. 运行时动态判断类类型,灵活度高;
  2. 支持动态加载类(比如加载配置文件中的类),降低代码耦合;
  3. 是框架设计的核心,能让框架更灵活(如 Spring 的 IOC)。
缺点
  1. 性能瓶颈:反射是 “解释式操作”,需要通知 JVM 执行,性能比直接调用代码慢很多;
  2. 安全隐患:通过setAccessible(true)能跳过访问检查,操作私有属性 / 方法,可能破坏类的封装性。

六、实际应用:反射在哪用?

虽然平时业务开发很少直接写反射,但它几乎无处不在,尤其是框架和工具类中:

  1. JDBC 连接数据库:用Class.forName("com.mysql.cj.jdbc.Driver")反射加载数据库驱动;
  2. Spring 框架:IOC 容器通过反射动态创建 Bean 实例,AOP 通过反射实现动态代理;
  3. 动态配置:比如通过配置文件(如 XML、YAML)指定类名,用反射动态创建实例、设置属性;
  4. 动态代理:MyBatis、Spring AOP 的代理逻辑,底层依赖反射调用目标方法。

七、总结

Java 反射机制是 “看似不用,实则离不开” 的核心特性 —— 它让程序从 “编译时固定” 走向 “运行时灵活”,成为框架设计的灵魂。虽然有性能和安全的小瑕疵,但只要合理使用(比如框架底层封装,避免频繁调用),就能最大化它的价值。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐