← 返回首页

Java注解详解

📂 java ⏱ 3 min 492 words

什么是注解

注解(Annotation)是JDK 5引入的一种元数据形式,可以附加在类、方法、字段等元素上。注解不影响程序的逻辑,但可以被编译器和运行时框架读取并处理。

内置注解

@Override

public class Animal {
    public String speak() {
        return "动物叫声";
    }
}

public class Dog extends Animal {
    @Override
    public String speak() {
        return "汪汪汪";
    }
}

@Deprecated

public class OldApi {
    @Deprecated
    public void oldMethod() {
        System.out.println("这是旧方法");
    }

    public void newMethod() {
        System.out.println("这是新方法");
    }
}

public class DeprecatedDemo {
    public static void main(String[] args) {
        OldApi api = new OldApi();
        api.oldMethod();
        api.newMethod();
    }
}

@SuppressWarnings

import java.util.ArrayList;
import java.util.List;

public class SuppressWarningDemo {
    @SuppressWarnings("unchecked")
    public List<String> getRawList() {
        List rawList = new ArrayList();
        rawList.add("Java");
        return rawList;
    }

    @SuppressWarnings({"unused", "deprecation"})
    public void unusedVariable() {
        int x = 10;
        System.out.println("变量未使用");
    }
}

元注解

元注解是用来定义注解的注解。

@Target

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyMethodAnnotation {
}

@Retention

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeAnnotation {
    String value() default "";
}

@Documented和@Inherited

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Persistent {
    String tableName() default "";
    int version() default 1;
}

自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInfo {
    String name();
    String type();
    int length() default 255;
    boolean required() default false;
}

使用自定义注解

public class User {
    @FieldInfo(name = "user_id", type = "BIGINT", required = true)
    private Long id;

    @FieldInfo(name = "username", type = "VARCHAR", length = 50, required = true)
    private String username;

    @FieldInfo(name = "email", type = "VARCHAR", length = 100)
    private String email;

    public Long getId() { return id; }
    public String getUsername() { return username; }
    public String getEmail() { return email; }
}

注解处理器

import java.lang.reflect.Field;
import java.util.StringJoiner;

public class AnnotationProcessor {
    public static String generateSQL(Class<?> clazz) {
        StringJoiner joiner = new StringJoiner(", ", "(", ")");
        String tableName = clazz.getSimpleName().toLowerCase();

        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(FieldInfo.class)) {
                FieldInfo info = field.getAnnotation(FieldInfo.class);
                String column = info.name();
                String type = info.type();
                int length = info.length();
                boolean required = info.required();

                String columnDef = column + " " + type;
                if ("VARCHAR".equals(type)) {
                    columnDef += "(" + length + ")";
                }
                if (required) {
                    columnDef += " NOT NULL";
                }
                joiner.add(columnDef);
            }
        }

        return "CREATE TABLE " + tableName + " " + joiner + ";";
    }

    public static void main(String[] args) {
        String sql = generateSQL(User.class);
        System.out.println("生成的SQL:");
        System.out.println(sql);
    }
}

实际应用场景

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

import java.lang.reflect.Method;

public class LogProcessor {
    public static void process(Object obj) {
        Class<?> clazz = obj.getClass();
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(Log.class)) {
                Log log = method.getAnnotation(Log.class);
                System.out.printf("模块: %s, 操作: %s, 方法: %s%n",
                    log.module(), log.action(), method.getName());
            }
        }
    }
}

public class UserService {
    @Log(action = "创建用户", module = "用户管理")
    public void createUser(String name) {
        System.out.println("创建用户: " + name);
    }

    @Log(action = "删除用户", module = "用户管理")
    public void deleteUser(Long id) {
        System.out.println("删除用户: " + id);
    }
}

注解最佳实践

  1. 注解应该简洁明了,避免过度使用
  2. 合理设置默认值减少使用复杂度
  3. 选择合适的保留策略(SOURCE/CLASS/RUNTIME)
  4. 注解处理器要考虑性能影响
  5. 结合反射机制实现动态处理

总结

Java注解是一种强大的元数据机制,广泛应用于框架开发和代码配置中。理解注解的定义、元注解和处理器原理,能帮助你更好地理解和使用各种Java框架。