Java注解

注解简介

注解是Java 5引入的一种元数据机制,它提供了一种在代码中添加信息的方式,这些信息可以被编译器、IDE和运行时环境使用。

注解的基本概念

// 内置注解示例 @Override public String toString() { return "Hello"; } @Deprecated public void oldMethod() { // 已废弃的方法 } @SuppressWarnings("unchecked") public void processList() { List list = new ArrayList(); // 处理列表 }

注解类型

Java中的注解可以分为三种类型:内置注解、元注解和自定义注解。

// 内置注解 @Override @Deprecated @SuppressWarnings @SafeVarargs @FunctionalInterface // 元注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Repeatable // 自定义注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value() default ""; int count() default 0; String[] tags() default {}; }

自定义注解

可以通过@interface关键字定义自定义注解,并指定其属性和使用范围。

// 定义注解 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Author { String name(); String date(); String[] reviewers() default {}; } // 使用注解 @Author( name = "张三", date = "2024-03-20", reviewers = {"李四", "王五"} ) public class MyClass { @Author(name = "张三", date = "2024-03-20") public void myMethod() { // 方法实现 } }

注解处理

可以通过反射机制在运行时处理注解,或者使用注解处理器在编译时处理注解。

// 运行时处理注解 public class AnnotationProcessor { public static void processAnnotations(Class clazz) { // 获取类上的注解 Author author = clazz.getAnnotation(Author.class); if (author != null) { System.out.println("作者:" + author.name()); System.out.println("日期:" + author.date()); System.out.println("审阅者:" + Arrays.toString(author.reviewers())); } // 获取方法上的注解 for (Method method : clazz.getMethods()) { Author methodAuthor = method.getAnnotation(Author.class); if (methodAuthor != null) { System.out.println("方法:" + method.getName()); System.out.println("作者:" + methodAuthor.name()); System.out.println("日期:" + methodAuthor.date()); } } } }

常用注解

Java提供了许多内置注解,用于不同的场景。

// 1. 编译时注解 @Override public void method() { // 重写父类方法 } @Deprecated public void oldMethod() { // 已废弃的方法 } @SuppressWarnings("unchecked") public void processList() { List list = new ArrayList(); } // 2. 运行时注解 @Test public void testMethod() { // 测试方法 } @Autowired private UserService userService; // 3. 文档注解 /** * 这是一个示例方法 * @param name 用户名 * @return 欢迎消息 */ public String welcome(String name) { return "Welcome, " + name; }

注解继承

通过@Inherited元注解,可以使注解被子类继承。

// 定义可继承的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface InheritedAnnotation { String value() default ""; } // 使用注解 @InheritedAnnotation("父类") public class Parent { // 父类内容 } // 子类继承父类的注解 public class Child extends Parent { // 子类内容 } // 验证注解继承 public class InheritanceDemo { public static void main(String[] args) { // 获取子类上的注解 InheritedAnnotation annotation = Child.class.getAnnotation(InheritedAnnotation.class); System.out.println("注解值:" + annotation.value()); } }

注解组合

可以通过@Repeatable元注解使注解可以重复使用,或者通过注解组合实现更复杂的功能。

// 定义可重复的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Authors.class) public @interface Author { String name(); String date(); } // 定义容器注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Authors { Author[] value(); } // 使用重复注解 @Author(name = "张三", date = "2024-03-20") @Author(name = "李四", date = "2024-03-21") public class MyClass { // 类的内容 } // 处理重复注解 public class RepeatableDemo { public static void main(String[] args) { // 获取所有Author注解 Author[] authors = MyClass.class.getAnnotationsByType(Author.class); for (Author author : authors) { System.out.println("作者:" + author.name()); System.out.println("日期:" + author.date()); } } }

实践练习

练习1:实现一个简单的验证注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
    int min() default 0;
    int max() default 100;
    String pattern() default "";
}

public class Validator {
    public static void validate(Object obj) {
        // 实现字段验证逻辑
    }
}