Java注解是一種元數據,用于為代碼添加額外信息,不影響程序邏輯,但可被編譯器或運行時讀取處理。1. 注解分為編譯時、運行時和源碼時三種類型,分別用于編譯檢查、運行時反射操作和僅存在于源碼中;2. @target 用于指定注解適用的元素類型,如類、方法、字段等,提升代碼安全性與可讀性;3. @retention 指定注解的生命周期,包括source、class和runtime,決定其在不同階段是否可用;4. @documented 控制注解是否包含在javadoc中,增強api文檔可讀性;5. @inherited 控制注解是否可被子類繼承,僅適用于類注解,接口注解不會被繼承。
Java注解(Annotation)本質上是一種元數據,它提供了一種為代碼添加額外信息的方式,而這些信息本身并不是程序邏輯的一部分。你可以把它想象成代碼上的標簽,編譯器或運行時環境可以讀取這些標簽,并根據標簽執行相應的操作。
注解就像是代碼的便簽,可以告訴編譯器或運行時環境一些額外的信息。
解決方案
Java注解可以分為三種:編譯時注解、運行時注解和源碼時注解。編譯時注解主要用于編譯器進行類型檢查或生成額外的代碼,運行時注解則可以在程序運行時通過反射機制獲取,用于實現各種高級功能,比如依賴注入、ORM等。源碼時注解通常只在源碼階段存在,不會被編譯到class文件中。
立即學習“Java免費學習筆記(深入)”;
注解的強大之處在于它的可定制性。你可以定義自己的注解,并指定注解可以應用的目標(類、方法、字段等)以及注解的生命周期(源碼、編譯時、運行時)。
@Target 的作用是什么?
@Target 注解用于指定注解可以應用的目標元素類型。例如,你可以使用 @Target(ElementType.METHOD) 來指定一個注解只能用于方法上,如果將它應用到類上,編譯器就會報錯。
Java中ElementType的取值包括:
- ElementType.TYPE: 類、接口(包括注解類型)、枚舉
- ElementType.FIELD: 字段、枚舉的常量
- ElementType.METHOD: 方法
- ElementType.PARAMETER: 方法參數
- ElementType.constructor: 構造器
- ElementType.LOCAL_VARIABLE: 局部變量
- ElementType.ANNOTATION_TYPE: 注解類型
- ElementType.PACKAGE: 包
- ElementType.TYPE_PARAMETER: 類型參數(JDK1.8新增)
- ElementType.TYPE_USE: 使用類型的任何地方(JDK1.8新增)
@Target 的合理使用可以提高代碼的可讀性和可維護性,避免不必要的錯誤。
@Retention 的作用是什么?
@Retention 注解用于指定注解的保留策略,即注解在哪個階段仍然可用。它有三個取值:
- RetentionPolicy.SOURCE: 注解僅存在于源碼中,編譯后會被丟棄。
- RetentionPolicy.CLASS: 注解會被編譯到 class 文件中,但在運行時會被 jvm 丟棄。
- RetentionPolicy.RUNTIME: 注解會被編譯到 class 文件中,并且在運行時可以通過反射機制獲取。
選擇合適的 RetentionPolicy 非常重要。如果注解只需要在編譯時使用,例如用于代碼生成,那么使用 RetentionPolicy.SOURCE 可以減少 class 文件的大小。如果需要在運行時動態獲取注解信息,那么必須使用 RetentionPolicy.RUNTIME。
@Documented 的作用是什么?
@Documented 是一個標記注解,用于指定該注解是否應該被包含在 JavaDoc 文檔中。如果一個注解被 @Documented 標記,那么在使用該注解的元素生成 JavaDoc 文檔時,該注解的信息也會被包含進去。這有助于提高 API 的可讀性和可理解性。
但是,并不是所有的注解都適合被包含在 JavaDoc 文檔中。通常只有那些對 API 的使用者有意義的注解才應該被 @Documented 標記。
@Inherited 的作用是什么?
@Inherited 注解用于指定一個注解是否可以被子類繼承。如果一個類被一個注解標記,并且該注解使用了 @Inherited,那么該類的子類也會自動繼承該注解。
需要注意的是,@Inherited 只能用于類注解,不能用于方法、字段等其他類型的注解。 此外,接口上的注解是不會被實現類繼承的,即使使用了 @Inherited。
例如,假設有一個注解 @MyAnnotation,并且使用了 @Inherited,如果一個類 BaseClass 被 @MyAnnotation 標記,那么 BaseClass 的子類 SubClass 也會自動被 @MyAnnotation 標記。