Java注解 #

一、注解概述 #

1.1 什么是注解 #

注解是Java 5引入的元数据机制,用于在代码中添加信息。

1.2 注解的作用 #

  • 提供信息给编译器
  • 编译时和部署时的代码处理
  • 运行时处理

二、内置注解 #

2.1 编译相关 #

java
// 抑制警告
@SuppressWarnings("unchecked")

// 标记过时
@Deprecated
public void oldMethod() { }

// 标记覆盖
@Override
public String toString() {
    return "override";
}

2.2 函数式接口 #

java
@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
}

2.3 SuppressWarnings参数 #

java
@SuppressWarnings("unchecked")    // 未检查转换
@SuppressWarnings("deprecation")  // 过时方法
@SuppressWarnings("rawtypes")     // 原始类型
@SuppressWarnings("unused")       // 未使用

三、自定义注解 #

3.1 基本语法 #

java
public @interface MyAnnotation {
    String value();
    int count() default 0;
}

// 使用
@MyAnnotation(value = "test", count = 5)
public class MyClass { }

// value可以省略
@MyAnnotation("test")
public class MyClass2 { }

3.2 注解属性类型 #

java
public @interface MyAnnotation {
    String name();
    int age();
    double price();
    boolean active();
    Class<?> type();
    MyEnum status();
    String[] tags();
}

四、元注解 #

4.1 @Target #

指定注解可以应用的位置。

java
@Target(ElementType.TYPE)           // 类、接口
@Target(ElementType.FIELD)          // 字段
@Target(ElementType.METHOD)         // 方法
@Target(ElementType.PARAMETER)      // 参数
@Target(ElementType.CONSTRUCTOR)    // 构造方法
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE)// 注解类型
@Target(ElementType.PACKAGE)        // 包

// 多个位置
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation { }

4.2 @Retention #

指定注解的保留策略。

java
@Retention(RetentionPolicy.SOURCE)  // 源码保留(编译时丢弃)
@Retention(RetentionPolicy.CLASS)   // 字节码保留(默认)
@Retention(RetentionPolicy.RUNTIME) // 运行时保留(反射可用)

4.3 @Documented #

指定注解是否包含在JavaDoc中。

java
@Documented
public @interface MyAnnotation { }

4.4 @Inherited #

指定注解是否被子类继承。

java
@Inherited
public @interface MyAnnotation { }

@MyAnnotation
public class Parent { }

public class Child extends Parent { }  // Child也有@MyAnnotation

4.5 @Repeatable #

指定注解是否可重复(Java 8+)。

java
@Repeatable(Tags.class)
public @interface Tag {
    String value();
}

public @interface Tags {
    Tag[] value();
}

// 使用
@Tag("A")
@Tag("B")
public class MyClass { }

五、运行时处理注解 #

5.1 获取类注解 #

java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
    String name();
}

@Table(name = "users")
public class User { }

// 获取注解
Class<User> clazz = User.class;
Table table = clazz.getAnnotation(Table.class);
if (table != null) {
    System.out.println(table.name());  // users
}

5.2 获取方法注解 #

java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Column {
    String name();
    String type() default "VARCHAR";
}

public class User {
    @Column(name = "user_name", type = "VARCHAR(50)")
    private String name;
}

// 获取字段注解
Field field = User.class.getDeclaredField("name");
Column column = field.getAnnotation(Column.class);
if (column != null) {
    System.out.println(column.name());  // user_name
    System.out.println(column.type());  // VARCHAR(50)
}

5.3 获取方法注解 #

java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
    String value();
}

public class Service {
    @Log("执行操作")
    public void doSomething() { }
}

// 获取方法注解
Method method = Service.class.getMethod("doSomething");
Log log = method.getAnnotation(Log.class);
if (log != null) {
    System.out.println(log.value());  // 执行操作
}

六、注解应用示例 #

6.1 简单ORM框架 #

java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
    String name();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    String name();
    boolean primaryKey() default false;
}

@Table(name = "t_user")
public class User {
    @Column(name = "id", primaryKey = true)
    private Long id;
    
    @Column(name = "name")
    private String name;
}

// 生成SQL
public class OrmUtils {
    public static String getCreateTableSQL(Class<?> clazz) {
        Table table = clazz.getAnnotation(Table.class);
        StringBuilder sql = new StringBuilder();
        sql.append("CREATE TABLE ").append(table.name()).append(" (");
        
        for (Field field : clazz.getDeclaredFields()) {
            Column column = field.getAnnotation(Column.class);
            if (column != null) {
                sql.append(column.name()).append(" ");
                sql.append(getSqlType(field.getType()));
                if (column.primaryKey()) {
                    sql.append(" PRIMARY KEY");
                }
                sql.append(", ");
            }
        }
        
        sql.delete(sql.length() - 2, sql.length());
        sql.append(")");
        return sql.toString();
    }
}

七、总结 #

元注解 说明
@Target 注解目标位置
@Retention 注解保留策略
@Documented 包含在JavaDoc
@Inherited 子类继承
@Repeatable 可重复使用

注解要点:

  • 使用@Retention(RUNTIME)才能运行时反射
  • 注解属性可以有默认值
  • value属性可以省略名称
  • 合理使用元注解
最后更新:2026-03-26