Java中注解与注释的区别以及注解详解(按框架分)和(按使用频率分)两种
一、注解 vs 注释:核心区别
| 维度 | 注释(Comment) | 注解(Annotation) |
|---|---|---|
| 定义 | 代码中的解释性文字,仅供开发者阅读。 | 代码中的元数据,用于向编译器、框架或运行时提供信息。 |
| 语法 | 使用 //、/* */、/** */ |
以 @ 符号开头(如 @Override),可包含参数(如 @RequestMapping("/path"))。 |
| 作用对象 | 任何代码(类、方法、变量等)。 | 类、方法、字段、参数、包等。 |
| 处理阶段 | 编译时被忽略,不会出现在字节码中。 | 可保留到编译时、类加载时或运行时(由 @Retention 指定)。 |
| 功能 | 无功能影响,仅辅助代码阅读。 | 影响编译行为、生成代码、配置框架、运行时逻辑等。 |
| 应用场景 | 解释代码逻辑、作者、修改记录等。 | 框架配置(如 Spring)、代码检查(如 @Override)、生成代码(如 Lombok)等。 |
| 示例 | // 计算用户年龄 |
@Override public String toString() { ... } |
二、注解的深入解析
1. 注解的基本概念
- 本质:一种元数据(metadata),用于描述代码的结构或行为。
- 作用:
- 编译时检查:如
@Override验证方法是否重写父类。 - 生成代码:如 Lombok 的
@Data自动生成 getter/setter。 - 运行时处理:如 Spring 的
@Autowired自动注入依赖。
- 编译时检查:如
2. 元注解(Meta-Annotation)
用于定义注解的注解,Java 内置 5 种元注解:
| 元注解 | 作用 |
|---|---|
@Target |
指定注解可应用的目标(如 ElementType.METHOD 表示只能用于方法)。 |
@Retention |
指定注解的保留策略(源码、编译时、运行时)。 |
@Documented |
将注解包含在 Javadoc 中。 |
@Inherited |
允许子类继承父类的注解。 |
@Repeatable |
允许在同一位置重复使用注解(Java 8+)。 |
示例:定义一个运行时注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "default";
int priority() default 0;
}
3. Java 内置常用注解
| 注解 | 用途 |
|---|---|
@Override |
标记方法重写父类方法,编译时检查方法签名是否正确。 |
@Deprecated |
标记代码已过时,使用时会生成警告。 |
@SuppressWarnings |
抑制编译器警告(如 @SuppressWarnings("unchecked"))。 |
@FunctionalInterface |
标记接口为函数式接口(仅允许一个抽象方法)。 |
@SafeVarargs |
标记方法参数为安全可变参数(抑制“堆污染”警告)。 |
4. 自定义注解的处理
通过反射(Reflection)在运行时读取注解信息:
public class AnnotationProcessor {
public static void main(String[] args) {
Method[] methods = MyClass.class.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("Method: " + method.getName());
System.out.println("Value: " + annotation.value());
System.out.println("Priority: " + annotation.priority());
}
}
}
}
三、常用第三方框架注解
1. Lombok 注解(代码生成)
| 注解 | 作用 | 示例 |
|---|---|---|
@Data |
自动生成 getter/setter、equals()、hashCode() 等。 |
@Data public class User { private String name; } |
@Builder |
生成 Builder 模式代码。 | @Builder public class Product { ... } |
@Slf4j |
自动注入日志对象(log)。 |
@Slf4j public class Service { ... } |
2. Spring 注解(依赖注入与配置)
| 注解 | 用途 |
|---|---|
@Autowired |
自动注入依赖对象(默认按类型匹配)。 |
@Component |
标记类为 Spring 组件(被扫描并注册为 Bean)。 |
@RequestMapping |
定义 HTTP 请求映射(如 @RequestMapping("/api"))。 |
@Transactional |
声明事务管理(方法或类级别)。 |
3. JUnit 注解(测试)
| 注解 | 用途 | 示例 |
|---|---|---|
@Test |
标记测试方法。 | @Test public void testMethod() { ... } |
@BeforeEach |
每个测试方法执行前运行。 | @BeforeEach void setup() { ... } |
@Mock |
创建 Mock 对象(需配合 Mockito)。 | @Mock private UserService userService; |
Java 常用注解大全(按使用频率排序)
一、高频注解(几乎每个项目必用)
1. @Override
-
用途:标记方法重写父类或接口的方法。
-
场景:任何继承或实现中需要覆盖的方法。
-
示例:
@Override public String toString() { return "This is an overridden method"; }
2. @SpringBootApplication
-
用途:标记 Spring Boot 主启动类,整合
@Configuration、@EnableAutoConfiguration和@ComponentScan。 -
场景:Spring Boot 项目的入口类。
-
示例:
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
3. @RestController
-
用途:标记类为 RESTful 控制器,整合
@Controller和@ResponseBody。 -
场景:定义 HTTP 接口的控制器类。
-
示例:
@RestController public class UserController { @GetMapping("/users") public List<User> getUsers() { ... } }
4. @Autowired
-
用途:自动注入依赖(默认按类型匹配)。
-
场景:Spring 管理的 Bean 之间的依赖注入。
-
示例:
@Autowired private UserService userService;
二、中高频注解(大部分项目常用)
5. @RequestMapping / @GetMapping / @PostMapping
-
用途:定义 HTTP 请求映射路径和方式。
-
场景:RESTful API 接口的方法级路由。
-
示例:
@PostMapping("/users") public User createUser(@RequestBody User user) { ... }
6. @Service / @Repository / @Component
-
用途:标记类为 Spring 管理的 Bean(分别用于服务层、数据层、通用组件)。
-
场景:Spring 的组件扫描和依赖注入。
-
示例:
@Service public class UserService { ... }
7. @Data (Lombok)
-
用途:自动生成 getter/setter、
equals()、hashCode()等方法。 -
场景:POJO 类(如实体类、DTO)。
-
示例:
@Data public class User { private String name; private int age; }
8. @Test (JUnit)
-
用途:标记方法为单元测试方法。
-
场景:JUnit 测试类中的测试用例。
-
示例:
@Test public void testAddUser() { ... }
9. @Slf4j (Lombok)
-
用途:自动生成日志对象
log(需配合 SLF4J 使用)。 -
场景:任何需要记录日志的类。
-
示例:
@Slf4j public class OrderService { public void createOrder() { log.info("Creating order..."); } }
10. @Configuration / @Bean
-
用途:标记配置类,并定义 Bean 的创建方式。
-
场景:Spring 的 Java 配置类。
-
示例:
@Configuration public class AppConfig { @Bean public DataSource dataSource() { ... } }
三、中频注解(特定场景常用)
11. @Transactional
-
用途:声明事务管理(方法或类级别)。
-
场景:数据库操作需要事务控制的场景。
-
示例:
@Transactional public void transferMoney(Account from, Account to, double amount) { ... }
12. @Entity / @Table (JPA)
-
用途:标记类为 JPA 实体,并映射数据库表。
-
场景:数据库实体类的定义。
-
示例:
@Entity @Table(name = "users") public class User { ... }
13. @Value
-
用途:注入配置文件中的属性值。
-
场景:读取
application.properties或application.yml中的配置。 -
示例:
@Value("${server.port}") private int port;
14. @Qualifier
-
用途:按名称指定注入的 Bean(配合
@Autowired使用)。 -
场景:存在多个同类型 Bean 时消除歧义。
-
示例:
@Autowired @Qualifier("userServiceV2") private UserService userService;
15. @Builder (Lombok)
-
用途:生成 Builder 模式代码。
-
场景:复杂对象的链式构造。
-
示例:
@Builder public class Product { private String id; private String name; }
四、低频注解(特殊需求使用)
16. @Async
-
用途:标记方法为异步执行。
-
场景:需要异步处理的任务(如发送邮件)。
-
示例:
@Async public void sendEmail(String to) { ... }
17. @Profile
-
用途:指定 Bean 在特定环境(如
dev、prod)下生效。 -
场景:多环境配置管理。
-
示例:
@Profile("dev") @Service public class MockUserService { ... }
18. @Retention / @Target
-
用途:元注解,定义自定义注解的保留策略和作用目标。
-
场景:开发自定义注解。
-
示例:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { ... }
19. @Scheduled
-
用途:标记方法为定时任务。
-
场景:周期性的任务调度。
-
示例:
@Scheduled(fixedRate = 5000) public void checkStatus() { ... }
20. @PreAuthorize (Spring Security)
-
用途:方法执行前的权限校验。
-
场景:基于角色的访问控制(RBAC)。
-
示例:
@PreAuthorize("hasRole('ADMIN')") public void deleteUser(String userId) { ... }
五、总结:如何选择注解?
- 高频注解:必须熟练掌握(如
@Override、@SpringBootApplication)。 - 中高频注解:根据技术栈选择(Spring、Lombok、JPA)。
- 中低频注解:按需学习(如定时任务、异步处理)。
附:注解使用注意事项
- Lombok 注解:需在 IDE 中安装 Lombok 插件。
- Spring 注解:确保配置类被正确扫描(
@ComponentScan)。 - 事务注解:默认仅对
RuntimeException回滚,需显式配置其他异常。
注解的核心价值:
- 提升代码简洁性:通过注解代替重复代码(如 Lombok)。
- 增强可维护性:通过元数据明确代码意图(如
@Override)。 - 支持框架扩展:通过注解配置框架行为(如 Spring、Hibernate)。
浙公网安备 33010602011771号