Java註解類型
標記註解類型
標記註解類型是沒有元素的註解類型,甚至沒有默認值。標記註解由註解處理工具使用。
public @interface Marker {
}
@Marker
public class Main{
}
元註解類型
元註解類型是註解類型,用於註解其他註解類型。元註解類型是Java類庫的一部分。它們在包java.lang.annotation
中聲明。
以下註解類型是元註解類型:
- 目標
- 保留
- 繼承
- 文檔記錄
- 可重複的
- 本地
目標註釋類型
目標註釋類型註釋註釋類型以設置上下文以使用註釋類型。它只有一個名爲value
的元素。 其值元素是java.lang.annotation.ElementType
枚舉類型的數組。下表列出了ElementType
枚舉中的所有常量。
常量名稱
描述
ANNOTATION_TYPE
註釋另一個註釋類型聲明,使註釋類型爲元註釋。
CONSTRUCTOR
註釋構造函數。
FIELD
註釋字段和枚舉常量。
LOCAL_VARIABLE
註釋局部變量。
METHOD
註釋方法。
PACKAGE
註釋包聲明。
PARAMETER
註釋參數。
TYPE
註釋類,接口(包括註釋類型)或枚舉聲明。
TYPE_PARAMETER
在通用類,接口,方法等中註釋類型參數。
TYPE_USE
註釋所有類型的使用。
以下Version
註釋類型具有目標元註釋,它指定Version
註釋類型可以與只有三種類型的程序元素一起使用:任何類型(類,接口,枚舉和註釋類型),構造函數和方法。
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD })
public @interface Version {
int major();
int minor();
}
Version
註釋不能用於除其Target
註釋中指定的三種類型之外的任何程序元素。
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE_USE })
@interface MyAnno {
}
@Target({ ElementType.TYPE_USE })
@interface MyAnno2 {
}
public class Main {
public void processData() throws @MyAnno Exception {
int roundedValue = (@MyAnno2 int) .02;
Main t = new @MyAnno Main();
}
}
如果不使用Target
註釋類型註釋註釋類型,則註釋類型可以用作任何聲明的修飾符,但類型參數聲明除外。
保留(Retention)註釋
保留(Retention)註釋設置註釋類型的保留策略。註釋可以在三個級別保留 -
- 僅源代碼
- 僅類文件,默認行爲。
- 類文件和運行時
保留(Retention
)元註釋類型指定Java應如何保留註釋。如果註釋類型具有「僅限源代碼」保留策略,則在編譯到類文件中時將刪除其實例。如果保留策略爲「僅類文件」,則其實例將保留在類文件中,但不能在運行時讀取。
如果保留策略爲「類文件和運行時」,則註釋實例保留在類文件中,並且它們可在運行時讀取。保留元註釋類型聲明一個名爲value
的元素,它是java.lang.annotation.RetentionPolicy
枚舉類型。
RetentionPolicy
枚舉有三個常量:SOURCE
,CLASS
和 RUNTIME
,它們分別用於指定僅源,僅類和類運行時的保留策略。
以下代碼在版本註釋類型上使用保留元註釋。它指定版本註釋應該在運行時可用。
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@interface Version {
int major();
int minor();
}
如果不對註釋類型使用保留元註釋,則其保留策略僅默認爲類文件。則將無法在運行時讀取這些註釋。在類文件中或在運行時,局部變量聲明上的註釋永遠不可用,而不考慮註釋類型的保留策略。
繼承註釋類型
繼承註釋類型是標記元註釋類型。如果註釋類型使用Inherited
元註釋註釋,則其實例將由子類聲明繼承。
如果使用註釋類型註釋除類聲明以外的任何元素,它沒有任何效果。以下代碼顯示了[@Inherited](https://github.com/Inherited "@Inherited")
元註釋類型的效果。
import java.lang.annotation.Inherited;
@interface Ann2 {
int id();
}
@Inherited
@interface Ann3 {
int id();
}
@Ann2(id = 1)
@Ann3(id = 2)
class A {
}
// Class B inherits Ann3(id=2) annotation from the class A
class B extends A {
}
文檔註釋
文檔化註釋類型是標記元註釋類型。如果註釋類型用Documented
註解,Javadoc工具將爲其所有實例生成文檔。
import java.lang.annotation.Documented;
@Documented
@interface Version {
int major();
int minor();
}
@Version(major = 1, minor = 0)
public class Main {
}
當使用Javadoc工具爲Main
類生成文檔時,Main
類聲明上的Version
註釋也會作爲文檔的一部分生成。
可重複註釋
Java 8添加了可重複元註釋類型。如果在一個單獨的代碼元素上重複使用它,註釋類型聲明必須用[@Repeatable](https://github.com/Repeatable "@Repeatable")
來註解。
Repeatable
註釋類型只有一個名爲value
的元素,其類型是另一個註釋類型的類類型。
import java.lang.annotation.Repeatable;
@interface LogHistory {
Log[] value();
}
@Repeatable(LogHistory.class)
@interface Log {
String date();
String comments();
}
@Log(date = "01/01/2018", comments = "B")
@Log(date = "01/21/2018", comments = "A")
public class Main {
public static void process() {
}
}
本地註釋
本地(Native)註釋類型是元註釋,用於註釋可以從本地代碼引用的字段。它是一個標記註釋。