mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
900 字
2 分钟
Java注解详解
2026-02-03

注解这个东西,刚开始学的时候真没觉得有啥特别的,不就是几个@符号嘛。直到后来用Spring Boot写项目,@Autowired、@Service这些注解用顺手了,才意识到注解的威力。这篇文章把注解的方方面面梳理了一遍,希望能帮到你。

Java注解详解#

什么是注解?#

注解(Annotation)是Java 5引入的一种元编程特性,说白了就是在代码上贴标签,这些标签可以在编译时、类加载时或运行时被读取和处理。@Override、@Deprecated这些大家应该都用过,但真正理解注解的威力是在用了Spring之后。

注解的作用#

  1. 提供元数据——给代码加额外信息(作者、版本等)
  2. 编译时检查——比如@Override,写错了编译直接报错
  3. 代码生成——Lombok的@Getter、@Setter就是靠这个
  4. 运行时处理——Spring的@Autowired通过反射读取注解
  5. 配置替代——Spring Boot用注解替代XML配置

内置注解#

用于代码的

  • @Override——标记重写父类方法
  • @Deprecated——标记已过时
  • @SuppressWarnings——抑制编译器警告
  • @FunctionalInterface——标记函数式接口(Java 8+)
  • @Repeatable——标记注解可重复使用(Java 8+)

元注解(注解的注解)

  • @Target——指定注解能用在什么地方(类、方法、字段等)
  • @Retention——保留策略:SOURCE(源码)、CLASS(字节码)、RUNTIME(运行时)
  • @Documented——是否包含在Javadoc中
  • @Inherited——是否可以被继承

自定义注解#

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
String value() default "";
}

注解的属性类型有限制:基本类型、String、Class、枚举、注解、以及它们的数组。

元注解详解#

@Target#

指定注解的目标:

  • TYPE:类、接口、枚举
  • FIELD:字段
  • METHOD:方法
  • PARAMETER:方法参数
  • CONSTRUCTOR:构造方法
  • LOCAL_VARIABLE:局部变量
  • ANNOTATION_TYPE:注解类型
  • PACKAGE:包
  • TYPE_PARAMETER:类型参数(Java 8+)
  • TYPE_USE:类型使用(Java 8+)

@Retention#

指定保留策略:

  • SOURCE:只在源码中,编译时丢弃。比如@Override
  • CLASS:在class文件中,但运行时不可用。默认值
  • RUNTIME:运行时可以通过反射读取。@Autowired就是这种

@Inherited#

如果父类有@Inherited注解,子类会继承它。但只对类上的注解有效,方法和字段上的注解不会继承。

注解的处理#

运行时处理(通过反射)#

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
@Component("userService")
public class UserService {}
// 运行时读取注解
Class<?> clazz = UserService.class;
if (clazz.isAnnotationPresent(Component.class)) {
Component component = clazz.getAnnotation(Component.class);
System.out.println("Component name: " + component.value());
}

编译时处理(注解处理器)#

编译时处理需要写注解处理器(AbstractProcessor),编译时自动生成代码。Lombok就是这么干的。这个后面有专门的章节讲。

注解的应用场景#

  • 依赖注入:Spring的@Autowired@Component
  • 配置管理:Spring Boot的@Configuration@Bean
  • 方法路由:Spring MVC的@GetMapping@PostMapping
  • 数据验证:JSR-303的@NotNull@Size@Email
  • 测试框架:JUnit的@Test@Before
  • 代码生成:Lombok的@Data@Builder

常见陷阱#

  1. 保留策略搞错——需要运行时读取但用了SOURCE,反射拿不到
  2. @Inherited只对类有效——方法和字段上的注解不会被子类继承
  3. 反射获取注解的性能问题——频繁调用性能差,建议缓存结果

💡 实战贴士: 自定义注解如果只需要编译时处理(代码生成),用 RetentionPolicy.SOURCE 就够了,别用RUNTIME,因为运行时反射有性能开销。Lombok的@Getter就是SOURCE级别的,编译完就没了。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

部分信息可能已经过时

目录