跳转到内容

注解原理与应用

来自代码酷

简介[编辑 | 编辑源代码]

注解(Annotation)是Java 5引入的一种元数据机制,用于为代码提供附加信息。注解本身不直接影响程序逻辑,但可以通过反射或编译器处理实现特定功能(如代码生成、配置管理、框架集成等)。

核心特性[编辑 | 编辑源代码]

  • 编译时处理:通过APT(Annotation Processing Tool)生成代码(如Lombok的@Data)。
  • 运行时反射:通过java.lang.reflect读取注解信息(如Spring的@Autowired)。
  • 标记与配置:简化代码声明(如@Override@Deprecated)。

注解原理[编辑 | 编辑源代码]

注解的本质[编辑 | 编辑源代码]

注解是继承自java.lang.annotation.Annotation的接口,其行为由JVM和编译器共同控制。

classDiagram class Annotation { <<interface>> +annotationType() Class<? extends Annotation> } class RetentionPolicy { <<enum>> SOURCE, CLASS, RUNTIME } class ElementType { <<enum>> TYPE, FIELD, METHOD,... } Annotation <|-- UserDefinedAnnotation RetentionPolicy --> UserDefinedAnnotation ElementType --> UserDefinedAnnotation

元注解[编辑 | 编辑源代码]

定义注解行为的注解:

  • @Retention:指定生命周期(SOURCE/CLASS/RUNTIME)。
  • @Target:指定作用目标(类/方法/字段等)。
  • @Documented:是否包含在Javadoc中。
  • @Inherited:是否允许子类继承。
  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.METHOD)  
public @interface LogExecutionTime {  
    String value() default "defaultTask";  
}

注解应用[编辑 | 编辑源代码]

自定义注解示例[编辑 | 编辑源代码]

以下是一个记录方法执行时间的注解实现:

  
public class PerformanceMonitor {  
    public static void main(String[] args) throws Exception {  
        MyService service = new MyService();  
        Method method = service.getClass().getMethod("doTask");  
        if (method.isAnnotationPresent(LogExecutionTime.class)) {  
            long start = System.currentTimeMillis();  
            method.invoke(service);  
            long end = System.currentTimeMillis();  
            System.out.println("Execution time: " + (end - start) + "ms");  
        }  
    }  
}  

class MyService {  
    @LogExecutionTime("task1")  
    public void doTask() throws InterruptedException {  
        Thread.sleep(1000); // 模拟耗时操作  
    }  
}

输出

  
Execution time: 1002ms  

框架中的应用[编辑 | 编辑源代码]

  • Spring@Controller@RequestMapping通过反射解析路由。
  • JUnit@Test标记测试方法。
  • Hibernate@Entity定义数据库映射。

高级主题[编辑 | 编辑源代码]

注解处理器[编辑 | 编辑源代码]

通过继承AbstractProcessor实现编译时处理:

  
@SupportedAnnotationTypes("com.example.LogExecutionTime")  
@SupportedSourceVersion(SourceVersion.RELEASE_8)  
public class LogProcessor extends AbstractProcessor {  
    @Override  
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {  
        // 生成代码或报告编译错误  
        return true;  
    }  
}

性能考虑[编辑 | 编辑源代码]

  • 运行时反射读取注解会有性能开销,高频调用场景需缓存结果。
  • 编译时处理(如Lombok)无运行时开销。

常见问题[编辑 | 编辑源代码]

Q1:注解能继承吗?[编辑 | 编辑源代码]

默认不能,除非使用@Inherited元注解(仅对类生效)。

Q2:注解可以嵌套吗?[编辑 | 编辑源代码]

可以,但需将注解类型作为成员变量:

  
public @interface NestedAnnotation {  
    LogExecutionTime logConfig();  
}

总结[编辑 | 编辑源代码]

注解是Java中强大的元编程工具,广泛应用于框架开发、代码检查和配置管理。理解其原理和生命周期(SOURCE/CLASS/RUNTIME)是高效使用的关键。