java元註解詳解及自定義註解的方法

什麼是註解

註解相當於一種標記,開發工具、編譯器、JVM可以通過反射來了解類和元素有沒有註解,
然後去做出相應的操作。
例如 重寫方法時加上@Override註解,編譯器就會檢查該方法有沒有正確的覆蓋方法

修飾註解的註解:元註解

Retention註解

Retention註解用於限制註解信息保留的階段

@Retention註解有一個屬性value是RetentionPolicy類型的。
RetentionPolicy 有3個枚舉值:SOURCE CLASS RUNTIME
* @RetentinoPolicy(RetentionPolicy.SOURCE) 修飾註解時,該註解的信息只會保留
在源文件中,不會保留在class文件中,也不會被jvm讀取到運行時
* @RetentionPolicy(RetentionPolicy.CLASS) 修飾註解時,該註解的信息會保留在
class文件中,但是不會被jvm讀取
* @RetentionPolicy(RetentionPolicy.RUNTIME) 修飾註解時,該註解的信息會被保留
在class文件中,也會被jvm讀取從而保留到運行時

Target註解

Target註解限定註解適用的類型
Target的value屬性是一個ElementType枚舉類。
枚舉值有7個:
1. ElementType.CONSTRUCTOR —註解可以用於構造器
2. ElementType.FIELD —註解可以用於域聲明
3. ElementType.LOCAL_VARIABLE — 註解可以用於局部變量聲明
4. ElementType.METHOD — 註解可以用於方法聲明
5. ElementType.PACKAGE — 註解可以用於包聲明
6. ElementType.PARAMETER — 註解可以用於參數
7. ElementType.TYPE —註解可以用於類、接口、註解類型、enum聲明

Documented註解

Documented註解表明製作javadoc時,是否將註解信息加入文檔。如果註解在聲明時
使用了@Documented,則在製作javadoc時會將註解信息加入javadoc.

Inherited註解

表明註解是否會被子類繼承。默認情況子類不繼承父類註解。
當一個註解加了@Inherited元註解後,該註解會被使用了該註解的子類繼承

自定義註解的方法

定義註解類型跟一個定義一個接口類似
在interface關鍵字前面加一個@符號
註釋中的每一個方法定義了這個註釋類型的一個元素,
註釋中方法的聲明中一定不能包含參數,也不能拋出異常。
方法的返回值被限定爲基本類型、String、Class、enums、註釋以及這些類型的數組類型
方法可以有缺省值

自定義註解的例子

public @interface RequestForEnhancement{
    int id();
    String synopsis();
    String engineer() default "[unassigned]";
    String date(); default "[unimplemented]";
}

註解的用法:

@後面加註解名字,後面再跟上括號,括號中列出這個註釋中的元素以及對應
的值的列表。鍵值對中的值必須是常量。

使用註解的例子

@RequestForEnhancement{id=20142480117,synopsis="Enable time-travel",engineer="Mr.liu",date="4/1/3007"}

標記型註解

如果註解沒有元素,則該註解爲標記型註解(maker)。

標記型註解例子:

public @interface Test{}

在使用標記型註解時,後面的括號可以忽略。

只有一個元素的註解

如果註解只有一個元素,則該元素的名字應該爲value
使用該註解時元素的名字和等號可以省略

用自定義註解實現一個簡單的測試框架

  1. 定義註解Test
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test{}
  1. 在要測試的方法上加@Test註解
public claass TestCase{
    @Test
    public static void test1(){}
    @Test
    public static void test2(){
        System.out.println("test2");
    }
}
import java.lang.reflect.*;
public class TestCaseRun{
    public static void main(String args[]){
        Class clazz=TestCase.class;
        Method[] methods=clazz.getMethods();
        for(Method m:methods){
            if(m.isAnnotationPresent(Test.class){
                try{
                    m.invoke(null);
                }catch(Throwable ex){
                   System.out.println(ex.getCause());
                }
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章