1. 程式人生 > 實用技巧 >Java註解筆記(帶程式碼案例)

Java註解筆記(帶程式碼案例)

1、定義:註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。

2、作用分類:
①編寫文件:通過程式碼裡標識的註解生成文件【生成文件doc文件】
②程式碼分析:通過程式碼裡標識的註解對程式碼進行分析【使用反射】
③編譯檢查:通過程式碼裡標識的註解讓編譯器能夠實現基本的編譯檢查【Override】

3、JDK中預定義的一些註解
* @Override :檢測被該註解標註的方法是否是繼承自父類(介面)的;
* @Deprecated:該註解標註的內容,表示已過時;
* @SuppressWarnings:壓制警告,一般傳遞引數all @SuppressWarnings("all")。

4、自定義註解
* 格式:
元註解
public @interface 註解名稱{
屬性列表;
}

* 本質:註解本質上就是一個介面,該介面預設繼承Annotation介面
* public interface MyAnno extends java.lang.annotation.Annotation {}

* 屬性:介面中的抽象方法
* 要求:
(1)屬性的返回值型別有下列取值
* 基本資料型別
* String
* 列舉
* 註解
* 以上型別的陣列

(2) 定義了屬性,在使用時需要給屬性賦值
  a、如果定義屬性時,使用default關鍵字給屬性預設初始化值,則使用註解時,可以不進行屬性的賦值。
  b、如果只有一個屬性需要賦值,並且屬性的名稱是value,則value可以省略,直接定義值即可。
  c、陣列賦值時,值使用{}包裹。如果陣列中只有一個值,則{}可以省略

(3)元註解:用於描述註解的註解
* @Target:描述註解能夠作用的位置;
  ElementType取值:TYPE:可以作用於類上,METHOD:可以作用於方法上,FIELD:可以作用於成員變數上;
* @Retention:描述註解被保留的階段
* @Retention(RetentionPolicy.RUNTIME):當前被描述的註解,會保留到class位元組碼檔案中,並被JVM讀取到
* @Documented:描述註解是否被抽取到api文件中
* @Inherited:描述註解是否被子類繼承

5、案例:簡單測試框架

package com.lidaochen.test;


/**
 * 小明定義的計算器類
 */
public class Calculator {

    //加法
    @Check
    public void add(){
        String str = null;
        str.toString();
        System.out.println("1 + 0 =" + (1 + 0));
    }
    //減法
    @Check
    public void sub(){
        System.out.println(
"1 - 0 =" + (1 - 0)); } //乘法 @Check public void mul(){ System.out.println("1 * 0 =" + (1 * 0)); } //除法 @Check public void div(){ System.out.println("1 / 0 =" + (1 / 0)); } public void show(){ System.out.println("永無bug..."); } }
package com.lidaochen.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check {
}
package com.lidaochen.test;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.lang.reflect.Method;

public class CTestCheck {
    public static void main(String[] args) throws Exception {
        // 1、建立計算器物件
        Calculator calculator = new Calculator();
        // 2、獲取計算器 Class 位元組碼 檔案物件
        Class cls = calculator.getClass();
        // 3、獲取計算器類的所有方法
        Method[] methods = cls.getMethods();
        // 出現異常的次數
        int number = 0;
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("bug.txt"));
        for (Method method : methods) {
            // 判斷方法上是否有 Check 註解
            if(method.isAnnotationPresent(Check.class))
            {
                try {
                    // 有 Check 註解 執行方法
                    method.invoke(calculator);
                }
                catch (Exception e)
                {
                    // 捕獲異常
                    number++;
                    bufferedWriter.write(method.getName() + "方法出現了異常!");
                    bufferedWriter.newLine();
                    bufferedWriter.write("異常名稱:" + e.getCause().getClass().getSimpleName());
                    bufferedWriter.newLine();
                    bufferedWriter.write("異常原因:" + e.getCause().getMessage());
                    bufferedWriter.newLine();
                    bufferedWriter.write("--------------------------------------");
                    bufferedWriter.newLine();
                }
            }
        }
        bufferedWriter.write("本次測試一共出現了" + number + "次異常!");
        bufferedWriter.flush();
        bufferedWriter.close();
    }
}

6、案例:

package com.lidaochen.test;

public class CJavaTest {
    public void eat()
    {
        System.out.println("我喜歡吃西瓜!");
    }
}
package com.lidaochen.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Pro {
    String className();
    String methodName();
}
package com.lidaochen.test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;

@Pro(className = "com.lidaochen.test.CJavaTest", methodName = "eat")
public class CJavaDemo {
    public static void main(String[] args) throws Exception{
        // 1、獲取該類的位元組碼物件
        Class cls = CJavaDemo.class;
        // 2、獲取上邊的註解物件
        Pro an = (Pro) cls.getAnnotation(Pro.class);
        // 3、呼叫註解物件中定義的抽象方法,獲取返回值
        String className = an.className();
        String methodName = an.methodName();
        System.out.println(className);
        System.out.println(methodName);
        // 4、載入該類進記憶體
        Class mJavaTest = Class.forName(className);
        // 建立物件
        Object obj = mJavaTest.newInstance();
        // 獲取方法物件
        Method method = mJavaTest.getMethod(methodName);
        // 執行方法
        method.invoke(obj);
    }
}