首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 註解完整指南:從基礎語法到元註解、類型註解與重複註解實戰

     編輯:Java 綜合教學

什麼是註解?

Annotation(註解) 是一種元數據,提供「關於程序的程序級信息」,不直接影響業務邏輯執行。三大用途:

  1. 編譯器提示:錯誤檢查、抑制警告(@Override、@SuppressWarnings)
  2. 編譯時/部署時處理:代碼生成、配置文件產出(Lombok、MapStruct、MyBatis Generator)
  3. 運行時反射讀取:框架自動裝配、切面攔截(Spring @Autowired、JPA @Entity、JUnit @Test)

基礎語法


// 標記型(無元素)
@Override
@Deprecated

// 單元素(值名稱可省略為 value)
@SuppressWarnings("unchecked")
@MyAnnotation("singleValue")

// 多元素
@MyAnnotation(name = "test", version = 1, tags = {"a", "b"})

// Java 8+ 重複註解
@Schedule(dayOfWeek = "Mon")
@Schedule(dayOfWeek = "Wed")
public void run() { }

註解可用位置(Java 8+ 擴展為類型註解)

位置範例
類/介面/枚舉聲明@Entity class User {}
字段/方法/構造器/參數/局部變量@Autowired private UserService svc;
類型使用(Java 8 新增)new @NonNull String[]、(@NonNull String) obj、List<@Email String>、throws @Critical IOException

JDK 內建註解

java.lang 基礎註解

註解作用適用目標
@Override檢查是否正確重寫父類方法方法
@Deprecated標記棄用,編譯器警告類/方法/字段/構造器/包/參數
@SuppressWarnings抑制指定編譯器警告所有
@SafeVarargs抑制可變參數堆污染警告(Java 7+)方法/構造器
@FunctionalInterface標記函數式介面,編譯器校驗單一抽象方法(Java 8+)介面

java.lang.annotation 元註解

元註解作用關鍵屬性
@Retention生命週期SOURCE(源碼)、CLASS(字節碼,默認)、RUNTIME(運行時可反射)
@Target允許修飾的程序元素ElementType.TYPE/FIELD/METHOD/PARAMETER/CONSTRUCTOR/LOCAL_VARIABLE/ANNOTATION_TYPE/PACKAGE/TYPE_PARAMETER/TYPE_USE
@Documented包含在 Javadoc 中無
@Inherited子類自動繼承父類該註解(僅限 TYPE)無
@Repeatable允許同一位置重複使用(Java 8+)value = ContainerAnnotation.class

自定義註解實戰

1. 運行時反射讀取(框架常用)


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ApiOperation {
    String value() default "";
    String httpMethod() default "GET";
    int order() default 0;
}

// 使用
@ApiOperation(value = "用戶登錄", httpMethod = "POST", order = 1)
public Response login(@RequestBody LoginReq req) { ... }

// 反射讀取
Method m = UserController.class.getMethod("login", LoginReq.class);
ApiOperation op = m.getAnnotation(ApiOperation.class);
System.out.println(op.value() + " | " + op.httpMethod());

2. 編譯時處理(APT,如 Lombok)


// 註解定義
@Retention(RetentionPolicy.SOURCE)  // 僅源碼期保留
@Target(ElementType.TYPE)
public @interface GenerateBuilder { }

// 處理器(繼承 AbstractProcessor)
@SupportedAnnotationTypes("com.example.GenerateBuilder")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class BuilderProcessor extends AbstractProcessor {
    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        for (TypeElement te : env.getElementsAnnotatedWith(GenerateBuilder.class)) {
            // 生成 XXXBuilder.java 寫入 processingEnv.getFiler()
        }
        return true;
    }
}

// META-INF/services/javax.annotation.processing.Processor 註冊處理器類名

3. 重複註解容器模式


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Schedules.class)  // 指定容器註解
public @interface Schedule {
    String dayOfWeek();
    String time();
}

// 容器註解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Schedules {
    Schedule[] value();
}

// 使用
@Schedule(dayOfWeek = "Mon", time = "10:00")
@Schedule(dayOfWeek = "Fri", time = "15:00")
public void backup() { }

// 讀取(Java 8+ 自動合成容器)
Method m = BackupService.class.getMethod("backup");
Schedule[] arr = m.getAnnotationsByType(Schedule.class); // 直接獲取數組
// 或手動獲取容器
Schedules container = m.getAnnotation(Schedules.class);

類型註解與可插拔類型系統

Java 8 引入 TYPE_USE、TYPE_PARAMETER,配合 Checker Framework 實現編譯期強類型檢查:


// 非空檢查
public void setName(@NonNull String name) { ... }

// 正則檢查
public void setEmail(@Regex("[^@]+@[^@]+") String email) { }

// 不可變集合
List<@Readonly String> immutableList = ...;

// 編譯命令
javac -processor org.checkerframework.checker.nullness.NullnessChecker MyClass.java

反射 API 讀取註解(Java 8+ 增強)

方法行為重複註解處理
getAnnotation(Class<T>)返回單個註解(兼容模式:若有重複返回容器)返回容器註解
getAnnotationsByType(Class<T>)返回所有指定類型註解數組(含重複)自動展開容器,直接拿數組
getDeclaredAnnotationsByType(Class<T>)不包含繼承的註解同上

總結

  1. 註解三大階段:**SOURCE → CLASS → RUNTIME**,按需選擇 @Retention。
  2. @Target 精確限制使用位置,Java 8 新增 TYPE_USE/TYPE_PARAMETER 支援類型註解。
  3. 框架開發核心:運行時反射(Spring、JPA)或 編譯時 APT(Lombok、MapStruct、QueryDSL)。
  4. 重複註解靠 @Repeatable + 容器註解,讀取用 getAnnotationsByType()。
  5. 類型註解 + Checker Framework = **編譯期發現空指針、SQL注入、正則不匹配** 等邏輯錯誤,極大提升代碼質量。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved