【大白话说Java面试题】【Java基础篇】第39题:说说反射的用途及实现原理,Java获取反射(Class)的三种方法

0 阅读2分钟

📌 专栏:大白话说Java面试题 — 01-Java基础篇

第39题:说说反射的用途及实现原理,Java获取反射(Class)的三种方法

📚 回答:

  • 什么是反射?
    Java 的反射机制允许程序在运行时动态获取类的信息(如构造方法、成员变量、方法等),并动态调用对象的功能。这种能力使得程序更加灵活,能够处理未知类型的对象。

1. 反射的实现原理
  • 编译阶段

    • Java 程序在编译后会生成 .class 文件,这些文件包含了类的元信息(如类名、字段、方法等)。
  • 运行阶段

    • 当程序运行时,JVM 会将 .class 文件加载到内存中,并为每个类生成一个 Class 对象。
    • 通过 Class 对象,可以获取类的构造方法(Constructor)、成员变量(Field)、方法(Method)等信息,并动态操作这些内容。

2. 获取 Class 对象的三种方法
  • 方法1:通过类名获取

    Class<?> clazz = String.class;
    
  • 方法2:通过类路径获取

    Class<?> clazz = Class.forName("java.lang.String");
    
  • 方法3:通过实例化对象获取

    String str = "Hello";
    Class<?> clazz = str.getClass();
    

    💡 代码示例
    以下代码展示了如何通过反射创建对象并调用方法:

import java.lang.reflect.Method;

class Person {
    private String name;

    public Person() {}

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        // 获取 Class 对象
        Class<?> clazz = Class.forName("Person");

        // 创建实例
        Object obj = clazz.getDeclaredConstructor().newInstance();

        // 获取方法并调用
        Method setName = clazz.getMethod("setName", String.class);
        setName.invoke(obj, "Alice");

        Method getName = clazz.getMethod("getName");
        System.out.println(getName.invoke(obj)); // 输出 Alice
    }
}

3. 反射的应用场景
  • 框架开发

    • Spring 的 IoC 容器通过反射动态创建对象并实现依赖注入。
    • Spring MVC 通过反射调用控制器中的方法。
  • 动态代理

    • JDK 动态代理底层依赖反射机制。
  • JDBC 驱动加载

    • 使用 Class.forName() 加载数据库驱动(如 MySQL 驱动)。
  • 注解解析

    • 如 JUnit、Spring 等框架通过反射解析注解并执行相应逻辑。

    💡 面试官视角

  • 面试官可能会问“反射的优缺点是什么?”答:

    • 优点:灵活性高,能够动态操作类和对象。
    • 缺点:性能较低,破坏封装性,可能导致安全隐患。
  • 面试官可能会追问“如何提高反射性能?”答:可以通过缓存 MethodField 等对象减少重复获取的开销。