Java註解 annotation(一.簡介和定義)

一.什麼是註解

官方解釋:

Java 註解用於爲Java程序提供元數據。作爲元數據,註解不直接影響代碼的執行,但也有一些註解實際上可以用於這一目的。

什麼是元數據,即一種描述數據的數據。所以可以說註解是描述源代碼的數據。
簡單理解註解可以看出一個個標籤,用來標記你的代碼,是一種應用於類,方法,參數,變量,構造器及包的一種特殊修飾符。

二.註解的定義

註解和class,interface一樣也是一種類型,通過@interface定義
如下:

public @interface TestAnnotation {
    
}

三.元註解

註解的應用應用很簡單,我們用使用TestAnnotation註解,在你想註解的類中@TestAnnotation就可以了
如下(註解類):

@TestAnnotation
public class Test {
}

但是要想註解想要正常工作還需要元註解的幫助

1.什麼是元註解

元註解就是註解到註解上的註解,或者說元註解是一種基本註解,它能用來註解其他註解。
我們可以將元註解看成一種特殊的修飾符,用來解釋說明註解,它是註解的元數據。

2.元註解的種類

元註解一共用5種:

  • @Retention
    Retention意爲保留期,@Retention用來解釋說明一個註解的存活週期
    @Retention取值:
    • RetentionPolicy.SOURCE 註解只在源碼階段保留,在編譯器進行編譯時它將被丟棄忽視。
    • RetentionPolicy.CLASS 註解只被保留到編譯進行的時候,它並不會被加載到 JVM 中。
    • RetentionPolicy.RUNTIME 註解可以保留到程序運行的時候,它會被加載進入到 JVM 中,所以在程序運行時可以獲取到它們。
      示例:
@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {

}
  • @Documented
    表示將註解中的元素包含到 Javadoc 中去。

  • @Target
    指定註解應用的地方,用來限定註解的應用場景(類,方法,參數等等)
    取值如下:

    • ElementType.ANNOTATION_TYPE 可以給一個註解進行註解
    • ElementType.CONSTRUCTOR 可以給構造方法進行註解
    • ElementType.FIELD 可以給屬性進行註解
    • ElementType.LOCAL_VARIABLE 可以給局部變量進行註解
    • ElementType.METHOD 可以給方法進行註解
    • ElementType.PACKAGE 可以給一個包進行註解
    • ElementType.PARAMETER 可以給一個方法內的參數進行註解
    • ElementType.TYPE 可以給一個類型進行註解,比如類、接口、枚舉
  • @Inherited
    繼承的意思,當一個超類被@Inherited(@Inherited註解)註解的註解(A註解)進行過註解的話,如果它的子類沒有被如何其他註解進行註解,那麼這個子類就繼承了超類的註解(A註解)

@Retention(RetentionPolicy.CLASS)
@Inherited
public @interface TestAnnotation {
}

@TestAnnotation
public class TestA {
}

public class TestB extends TestA{

}

TestAnnotation 被@Retention註解,類TestA被@TestAnnotation註解,類TestB繼承類TestA,類TestB也擁有TestAnnotation註解

  • @Repeatable
    @Repeatable是自然可重複的意思。這是Java 1.8加進來的新特性
    在需要對同一種註解多次使用時,往往需要藉助@Repeatable
    舉個列子
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Roles {
    Role[] value();
}

@Repeatable(Roles.class)
public @interface Role {
    String role() default "";
}

@Role(role="husband")
@Role(role="father")
@Role(role="son")
public class Person {
}

上面的代碼@Repeatable註解了Role ,@Repeatable 後面括號中的類相當於一個容器註解

什麼是容器註解:
本身也是註解,用來存放其他註解
按照規定,它裏面必須要有一個 value 的屬性,屬性類型是一個被 @Repeatable 註解過的註解數組

@Role(role="husband"),role="husband"表示給Role這個註解的role屬性賦值,關於註解的屬性下面會說明。
Person 類需要多次使用@Role註解,所以這裏使用@Repeatable註解@Role

測試一下註解效果:

Annotation[] annotations = Person.class.getAnnotations();
        System.out.println(annotations.length);
        Roles p1=(Roles) annotations[0];
        for(Role t:p1.value()){
            System.out.println(t.role());
        }

打印如下:

1
husband
father
son

四.註解的屬性

註解的屬性也叫成員變量。註解只有成員變量,沒有方法。註解的成員變量在註解的定義中以“無參的方法”的形式來聲明,其方法名定義了該成員變量的名字,其返回值定義了該成員變量的類型。

  • 註解的屬性類型必須以下幾種:
    8中基本類型(byte,boolean,char,short,int,long,float,double,)和
    String,Enum,Class,annotation類型,以及這些類型的數組
public @interface TestAnnotation {
    int id();

    String msg();
}

上面代碼定義TestAnnotation 這個註解有id和msg兩個屬性。在使用的時候我們需要給它們賦值

  • 賦值方式:括號內以value=“”的形式賦值,多個屬性以'',''隔開
@TestAnnotation(id = 1, msg = "註解測試")
public class Test {
}
  • 註解中可以設置默認值,默認值用default關鍵字指定
    使用註解時對於指定了默認值的屬性,如果不需要修改,可以不賦值
public @interface TestAnnotation {
    int id() default 0;

    String msg() default "msg";
}

@TestAnnotation()
public class Test {
}
  • 當一個註解只有一個屬性且屬性名爲value時,使用此註解可以省略括號內的屬性名直接賦值
public @interface TestAnnotation {
    String value();
}

@TestAnnotation("1")
public class Test {
}
  • 如果註解沒有屬性,括號也可以省略
public @interface TestAnnotation {
}

@TestAnnotation
public class Test {
}

五.JDK預製註解

  • @Deprecated
    標記過時元素的註解,用來標識類,方法或者變量已過時,不建議使用。調用過時方法時編譯器會提醒。
  • @Override
    重寫註解,用來表示子類的方法是覆蓋父類的方法。
  • @SuppressWarnings
    抑制警告註解,用於抑制編譯器產生警告信息.
  • @SafeVarargs
    參數安全類型註解。它的目的是提醒開發者不要用參數做一些不安全的操作,它的存在會阻止編譯器產生 unchecked 這樣的警告。它是在 Java 1.7 的版本中加入的
  • @FunctionalInterface
    函數式接口(函數式接口可以很容易轉換爲 Lambda 表達式)註解,這個是 Java 1.8 版本引入的新特性。函數式編程很火,所以 Java 8 也及時添加了這個特性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章