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枚舉有三個常量:SOURCECLASSRUNTIME,它們分別用於指定僅源,僅類和類運行時的保留策略。

以下代碼在版本註釋類型上使用保留元註釋。它指定版本註釋應該在運行時可用。

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)註釋類型是元註釋,用於註釋可以從本地代碼引用的字段。它是一個標記註釋。