1. 程式人生 > 其它 >10-2 列舉類與註解----註解(Annotation)(2)註解的使用

10-2 列舉類與註解----註解(Annotation)(2)註解的使用

技術標籤:javajava

10-2 列舉類與註解----註解(Annotation)(2)註解的使用

  1. 理解Annotation:
    ① jdk 5.0 新增的功能
    ② Annotation 其實就是程式碼裡的特殊標記, 這些標記可以在編譯, 類載入, 執行時被讀取, 並執行相應的處理。通過使用 Annotation,程式設計師可以在不改變原有邏輯的情況下, 在原始檔中嵌入一些補充資訊。
    ③在JavaSE中,註解的使用目的比較簡單,例如標記過時的功能,忽略警告等。在JavaEE/Android中註解佔據了更重要的角色,例如用來配置應用程式的任何切面,代替JavaEE舊版中所遺留的繁冗程式碼和XML配置等。

  2. Annocation的使用示例
    示例一:生成文件相關的註解
    示例二:在編譯時進行格式檢查(JDK內建的三個基本註解)
    (1)@Override: 限定重寫父類方法, 該註解只能用於方法
    (2)@Deprecated: 用於表示所修飾的元素(類, 方法等)已過時。通常是因為所修飾的結構危險或存在更好的選擇
    (3)@SuppressWarnings: 抑制編譯器警告
    示例三:跟蹤程式碼依賴性,實現替代配置檔案功能


自定義 Annotation

  1. 如何自定義註解:參照@SuppressWarnings定義
    ① 註解宣告為:@interface
    ② 內部定義成員,通常使用value表示
    ③ 可以指定成員的預設值,使用default定義
    ④ 如果自定義註解沒有成員,表明是一個標識作用。

說明:
(1)定義新的 Annotation 型別使用 @interface 關鍵字
(2)自定義註解自動繼承了java.lang.annotation.Annotation介面
(3) Annotation 的成員變數在 Annotation 定義中以無引數方法的形式來宣告。其方法名和返回值定義了該成員的名字和型別。我們稱為配置引數。型別只能是八種基本資料型別、String型別、Class型別、enum型別、Annotation型別、以上所有型別的陣列。 
(4)可以在定義 Annotation 的成員變數時為其指定初始值, 指定成員變數的初始值可使用 default 關鍵字

(5)如果只有一個引數成員,建議使用引數名為value
(6)如果定義的註解含有配置引數,那麼使用時必須指定引數值,除非它有預設值。格式是“引數名 = 引數值”,如果只有一個引數成員,且名稱為value,可以省略“value=” 
(7)沒有成員定義的 Annotation 稱為標記; 包含成員變數的 Annotation 稱為元資料 Annotation
注意:①自定義註解必須配上註解的資訊處理流程(使用反射)才有意義。
②如果註解有成員,在使用註解時,需要指明成員的值。
③定義註解通過都會指明兩個元註解:Retention、Target


JDK 中的元註解

  1. jdk 提供的4種元註解
    元註解:對現有的註解進行解釋說明的註解
    (1)Retention:指定所修飾的 Annotation 的生命週期:
    ①RetentionPolicy.SOURCE:在原始檔中有效(即原始檔保留),編譯器直接丟棄這種策略的註釋
    ②RetentionPolicy.CLASS:在class檔案中有效(即class保留) , 當執行 Java 程式時, JVM 不會保留註解。 這是預設值
    ③RetentionPolicy.RUNTIME:在執行時有效(即執行時保留),當執行 Java 程式時, JVM 會保留註釋。程式可以通過反射獲取該註釋。
    在這裡插入圖片描述

只有宣告為RUNTIME生命週期的註解,才能通過反射獲取。
④Target:用於修飾 Annotation 定義, 用於指定被修飾的 Annotation 能用於
修飾哪些程式元素。 @Target 也包含一個名為 value 的成員變數
出現的頻率較低的:
⑤ Documented:表示所修飾的註解在被javadoc解析時,保留下來。
⑥Inherited:被它修飾的 Annotation 將具有繼承性。

  1. 通過反射獲取註解資訊 —到反射內容時系統講解

jdk 8 中註解的新特性:可重複註解、型別註解

  1. jdk 8 中註解的新特性
    (1)可重複註解:① 在MyAnnotation上宣告@Repeatable,成員值為MyAnnotations.class
    ② MyAnnotation的Target和Retention等元註解與MyAnnotations相同。
    (2) 型別註解:
    ①ElementType.TYPE_PARAMETER 表示該註解能寫在型別變數的宣告語句中(如:泛型宣告)。
    ②lementType.TYPE_USE 表示該註解能寫在使用型別的任何語句中。

MyAnnotation註解:

package java2;
 
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
 
@Inherited
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER, TYPE_USE})
public @interface MyAnnotation {
    String value() default "hello";
}

MyAnnotations註解:(陣列)

package java2;
 
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
import static java.lang.annotation.ElementType.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotations {
    MyAnnotation[] value();
}

AnnotationTest:

package java2;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Date;

public class AnnotationTest {
    public static void main(String[] args) {
        Person p = new Student();
        p.walk();

        Date date = new Date(2020, 10, 11);
        System.out.println(date);

        @SuppressWarnings("unused")
        int num = 10;
//        System.out.println(num);

        @SuppressWarnings({ "unused", "rawtypes" })
        ArrayList list = new ArrayList();
    }

    @Test
    public void testGetAnnotation(){
        Class clazz = Student.class;
        Annotation[] annotations = clazz.getAnnotations();
        for(int i = 0;i < annotations.length;i++){
            System.out.println(annotations[i]);
        }
    }
}


//jdk 8之前的寫法:
//@MyAnnotations({@MyAnnotation(value="hi"),@MyAnnotation(value="hi")})
@MyAnnotation(value="hi")
@MyAnnotation(value="abc")
class Person{
    private String name;
    private int age;

    public Person() {
    }
    @MyAnnotation
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @MyAnnotation
    public void walk(){
        System.out.println("人走路");
    }
    public void eat(){
        System.out.println("人吃飯");
    }
}

interface Info{
    void show();
}

class Student extends Person implements Info{
    @Override
    public void walk() {
        System.out.println("學生走路");
    }
    public void show() {
    }
}

class Generic<@MyAnnotation T>{

    public void show() throws @MyAnnotation RuntimeException{

        ArrayList<@MyAnnotation String> list = new ArrayList<>();
 
        int num = (@MyAnnotation int) 10L;
    }
}

輸出:

學生走路
Thu Nov 11 00:00:00 CST 3920