Skip to content

注解

注解概述

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

内置注解

java
// @Override - 方法重写
@Override
public String toString() {
    return "override method";
}

// @Deprecated - 已过时
@Deprecated
public void oldMethod() {
    // 旧方法
}

// @SuppressWarnings - 抑制警告
@SuppressWarnings("unchecked")
public void suppressWarnings() {
    List list = new ArrayList();
}

// @FunctionalInterface - 函数式接口
@FunctionalInterface
public interface MyFunction {
    void apply();
}

元注解

元注解用于定义注解的注解。

@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_USE)     // 类型使用(Java 8+)
@Target(ElementType.TYPE_PARAMETER) // 类型参数(Java 8+)

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

@Retention

指定注解的保留策略:

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

@Documented

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

java
@Documented
public @interface MyAnnotation {
}

@Inherited

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

java
@Inherited
public @interface MyAnnotation {
}

@Repeatable

指定注解是否可重复使用(Java 8+):

java
@Repeatable(Authors.class)
public @interface Author {
    String name();
}

public @interface Authors {
    Author[] value();
}

// 使用
@Author(name = "张三")
@Author(name = "李四")
public class Book {
}

自定义注解

基本定义

java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "";
    int count() default 0;
    String[] tags() default {};
}

使用自定义注解

java
public class AnnotationDemo {
    @MyAnnotation(value = "test", count = 10, tags = {"a", "b"})
    public void method() {
    }
    
    // value可以省略名称
    @MyAnnotation("simple")
    public void simpleMethod() {
    }
}

注解属性类型

java
public @interface Types {
    // 基本类型
    int intValue();
    long longValue();
    double doubleValue();
    boolean booleanValue();
    
    // String
    String stringValue();
    
    // Class
    Class<?> classValue();
    
    // 枚举
    ElementType enumValue();
    
    // 注解
    Deprecated annotationValue();
    
    // 数组
    String[] arrayValue();
    
    // 默认值
    String name() default "default";
}

注解处理器

运行时处理

java
import java.lang.reflect.Method;

public class AnnotationProcessor {
    public static void process(Class<?> clazz) {
        // 检查类上的注解
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("类注解: " + annotation.value());
        }
        
        // 检查方法上的注解
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("方法 " + method.getName() + 
                    " 注解: " + annotation.value());
            }
        }
    }
}

实战示例:简易ORM

java
import java.lang.annotation.*;
import java.lang.reflect.Field;

// 表名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String name();
}

// 列名注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String name();
    String type() default "VARCHAR(255)";
}

// 实体类
@Table(name = "users")
public class User {
    @Column(name = "id", type = "INT PRIMARY KEY")
    private int id;
    
    @Column(name = "username")
    private String username;
    
    @Column(name = "email")
    private String email;
    
    // getters and setters
}

// SQL生成器
public class SqlGenerator {
    public static String createTable(Class<?> clazz) {
        StringBuilder sql = new StringBuilder("CREATE TABLE ");
        
        Table table = clazz.getAnnotation(Table.class);
        if (table == null) {
            throw new RuntimeException("No Table annotation");
        }
        sql.append(table.name()).append(" (\n");
        
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            Column column = field.getAnnotation(Column.class);
            if (column != null) {
                sql.append("  ").append(column.name())
                   .append(" ").append(column.type());
                if (i < fields.length - 1) {
                    sql.append(",");
                }
                sql.append("\n");
            }
        }
        sql.append(")");
        return sql.toString();
    }
    
    public static void main(String[] args) {
        System.out.println(createTable(User.class));
    }
}

实战示例:方法日志

java
import java.lang.annotation.*;
import java.lang.reflect.*;

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

public class LogHandler implements InvocationHandler {
    private Object target;
    
    public LogHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Log log = method.getAnnotation(Log.class);
        if (log != null) {
            System.out.println("执行方法: " + method.getName() + 
                ", 日志: " + log.value());
        }
        return method.invoke(target, args);
    }
    
    @SuppressWarnings("unchecked")
    public static <T> T createProxy(T target) {
        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new LogHandler(target)
        );
    }
}

// 使用
interface UserService {
    @Log("查询用户")
    void getUser(int id);
    
    @Log("保存用户")
    void saveUser(String name);
}

public class UserServiceImpl implements UserService {
    @Override
    public void getUser(int id) {
        System.out.println("获取用户: " + id);
    }
    
    @Override
    public void saveUser(String name) {
        System.out.println("保存用户: " + name);
    }
}

// 测试
UserService service = LogHandler.createProxy(new UserServiceImpl());
service.getUser(1);
service.saveUser("张三");

常用框架注解

Spring注解

java
@Component      // 组件
@Service        // 服务层
@Repository     // 数据访问层
@Controller     // 控制器
@Autowired      // 自动注入
@Qualifier      // 指定注入Bean
@Value          // 注入配置值
@Configuration  // 配置类
@Bean           // Bean定义
@Scope          // 作用域
@Transactional  // 事务
@RequestMapping  // 请求映射
@GetMapping     // GET请求
@PostMapping    // POST请求

JPA注解

java
@Entity         // 实体类
@Table          // 表名
@Id             // 主键
@GeneratedValue  // 自动生成
@Column         // 列定义
@OneToMany      // 一对多
@ManyToOne      // 多对一
@ManyToMany     // 多对多

Jackson注解

java
@JsonProperty      // 属性名映射
@JsonIgnore        // 忽略属性
@JsonFormat        // 日期格式
@JsonInclude       // 包含策略
@JsonPropertyOrder // 属性顺序