Java 反射与注解机制
本模块面试重点
- 反射能做什么:运行时获取类信息、动态创建对象、调用方法、读写字段,是 Spring、MyBatis 等框架的基础能力。
- 反射的代价与使用场景:理解反射的性能开销、可见性问题(破坏封装),知道在业务代码中应“少量使用、框架多用”。
- 注解的作用:知道自定义注解 + 反射可以实现通用能力(如校验、AOP、配置映射),理解常见注解的元注解含义(
@Target、@Retention等,了解即可)。
❓ 面试官:什么是反射?反射能做什么?它有什么优缺点?
频率:🔥🔥🔥🔥
💡 一句话总结(先抛结论): 反射(Reflection)是 Java 提供的一种在运行时动态获取类的信息、创建对象、调用方法的机制。它是很多框架(如 Spring、MyBatis)的底层基石。
📝 详细原理解析:
反射能做什么?
- 在运行时获取类的字段、方法、构造器等信息。
- 动态创建对象(即使不知道类名,通过字符串也能创建)。
- 动态调用方法(通过方法名字符串调用)。
- 获取并修改字段的值(包括私有字段)。
代码示例:
java
// 传统方式:编译期必须知道类名
User user = new User();
// 反射方式:运行时才知道类名
Class<?> clazz = Class.forName("com.example.User");
Object user = clazz.newInstance(); // 创建对象
Method method = clazz.getMethod("setName", String.class);
method.invoke(user, "张三"); // 调用方法🌟 优缺点分析:
- 优点:灵活性极高,框架可以动态加载和操作类,实现解耦。
- 缺点:
- 性能较差:反射调用比直接调用慢 10-100 倍(因为要解析类信息、安全检查等)。
- 代码可读性差:反射代码难以理解和维护。
- 破坏封装性:可以访问私有成员,违背了面向对象的封装原则。
🔥 实战应用场景: "Spring 框架在启动时,会扫描所有带 @Component、@Service 等注解的类,利用反射创建 Bean 实例并放入容器。MyBatis 在执行 SQL 时,也是通过反射将查询结果映射到实体类对象中。"
❓ 面试官:Java 中的注解(Annotation)是什么?@Override、@Deprecated、@SuppressWarnings 这些内置注解的作用是什么?
频率:🔥🔥🔥
💡 一句话总结(先抛结论): 注解是一种元数据(描述数据的数据),它本身不执行任何逻辑,但可以被编译器、框架或运行时环境读取并处理。
📝 内置注解详解:
@Override:- 标记方法重写父类方法。
- 作用:编译期检查,如果方法签名写错了(比如拼写错误),编译器会报错,避免运行时才发现问题。
@Deprecated:- 标记类、方法或字段已过时,不推荐使用。
- 效果:IDE 会显示删除线,调用时会提示警告。
@SuppressWarnings:- 抑制编译器警告(如未使用的变量、泛型警告等)。
- 使用场景:当你确定代码没问题,但编译器一直报黄线警告时使用。
🌟 自定义注解(框架开发必备):
java
@Target(ElementType.METHOD) // 注解可以用在方法上
@Retention(RetentionPolicy.RUNTIME) // 注解保留到运行时
public @interface MyLog {
String value() default ""; // 注解的属性
}
// 使用
@MyLog("记录用户操作")
public void doSomething() {
// ...
}🔥 实战应用(加分项): "在项目中,我们经常自定义注解来实现 AOP 切面。比如定义一个 @RequireLogin 注解,打在需要登录的接口上。然后写一个切面类,拦截所有带这个注解的方法,统一做登录校验,代码非常优雅。"