標籤:ima default var test class類 element 決定 ret lan
Java用 @interface Annotation{ } 定義一個註解 @Annotation,一個註解是一個類。
@Override,@Deprecated,@SuppressWarnings為常見的3個註解。
註解相當於一種標記,在程式中加上了註解就等於為程式加上了某種標記,以後,
JAVAC編譯器,開發工具和其他程式可以用反射來瞭解你的類以及各種元素上有無任何標記,看你有什麼標記,就去幹相應的事。
註解@Override用在方法上,當我們想重寫一個方法時,在方法上加@Override,當我們方法
的名字出錯時,編譯器就會報錯,
註解@Deprecated,用來表示某個類的屬性或方法已經過時,不想別人再用時,在屬性和方法
上用@Deprecated修飾,
註解@SuppressWarnings用來壓製程序中出來的警告,比如在沒有用泛型或是方法已經過時的時候,
註解@Retention可以用來修飾註解,是註解的註解,稱為元註解。
Retention註解有一個屬性value,是RetentionPolicy類型的,Enum RetentionPolicy是一個枚舉類型,
這個枚舉決定了Retention註解應該如何去保持,也可理解為Rentention 搭配 RententionPolicy使用。RetentionPolicy有3個值:CLASS RUNTIME SOURCE
用@Retention(RetentionPolicy.CLASS)修飾的註解,表示註解的資訊被保留在class檔案(位元組碼檔案)中當程式編譯時間,但不會被虛擬機器讀取在啟動並執行時候;
用@Retention(RetentionPolicy.SOURCE )修飾的註解,表示註解的資訊會被編譯器拋棄,不會留在class檔案中,註解的資訊只會留在源檔案中;
用@Retention(RetentionPolicy.RUNTIME )修飾的註解,表示註解的資訊被保留在class檔案(位元組碼檔案)中當程式編譯時間,會被虛擬機器保留在運行時,
所以他們可以用反射的方式讀取。RetentionPolicy.RUNTIME 可以讓你從JVM中讀取Annotation註解的資訊,以便在剖析器的時候使用.
package com.self;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface MyTarget{ }定義個一註解@MyTarget,用RetentionPolicy.RUNTIME修飾;package com.self;import java.lang.reflect.Method;public class MyTargetTest{ @MyTarget public void doSomething() { System.out.println("hello world"); } public static void main(String[] args) throws Exception { Method method = MyTargetTest.class.getMethod("doSomething",null); if(method.isAnnotationPresent(MyTarget.class))//如果doSomething方法上存在註解@MyTarget,則為true { System.out.println(method.getAnnotation(MyTarget.class)); } }}上面程式列印:@com.self.MyTarget(),如果RetentionPolicy值不為RUNTIME,則不列印。 @Retention(RetentionPolicy.SOURCE )public @interface Override@Retention(RetentionPolicy.SOURCE )public @interface SuppressWarnings@Retention(RetentionPolicy.RUNTIME )public @interface Deprecated由上可以看出,只有註解@Deprecated在運行時可以被JVM讀取到註解中可以定義屬性,看例子:@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation{ String hello() default "gege"; String world(); int[] array() default { 2, 4, 5, 6 }; EnumTest.TrafficLamp lamp() ; TestAnnotation lannotation() default @TestAnnotation(value = "ddd"); Class style() default String.class;}上面程式中,定義一個註解@MyAnnotation,定義了6個屬性,他們的名字為:hello,world,array,lamp,lannotation,style.屬性hello類型為String,預設值為gege屬性world類型為String,沒有預設值屬性array類型為數組,預設值為2,4,5,6屬性lamp類型為一個枚舉,沒有預設值屬性lannotation類型為註解,預設值為@TestAnnotation,註解裡的屬性是註解屬性style類型為Class,預設值為String類型的Class類型看下面例子:定義了一個MyTest類,用註解@MyAnnotation修飾,註解@MyAnnotation定義的屬性都賦了值@MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)public class MyTest{ @MyAnnotation(lannotation[email protected](value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW) @Deprecated @SuppressWarnings("") public void output() { System.out.println("output something!"); }} 接著通過反射讀取註解的資訊:public class MyReflection{ public static void main(String[] args) throws Exception { MyTest myTest = new MyTest(); Class<MyTest> c = MyTest.class; Method method = c.getMethod("output", new Class[] {}); //如果MyTest類名上有註解@MyAnnotation修飾,則為true if(MyTest.class.isAnnotationPresent(MyAnnotation.class)) { System.out.println("have annotation"); } if (method.isAnnotationPresent(MyAnnotation.class)) { method.invoke(myTest, null); //調用output方法 //擷取方法上註解@MyAnnotation的資訊 MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class); String hello = myAnnotation.hello(); String world = myAnnotation.world(); System.out.println(hello + ", " + world);//列印屬性hello和world的值 System.out.println(myAnnotation.array().length);//列印屬性array數組的長度 System.out.println(myAnnotation.lannotation().value()); //列印屬性lannotation的值 System.out.println(myAnnotation.style()); } //得到output方法上的所有註解,當然是被RetentionPolicy.RUNTIME修飾的 Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation.annotationType().getName()); } }}上面程式列印:have annotationoutput something!gege, shanghai3babyclass java.lang.Stringcom.heima.annotation.MyAnnotationjava.lang.Deprecated如果註解中有一個屬性名稱字叫value,則在應用時可以省略屬性名稱字不寫。可見,@Retention(RetentionPolicy.RUNTIME )註解中,RetentionPolicy.RUNTIME是註解屬性值,屬性名稱字是value,屬性的傳回型別是RetentionPolicy,如下:public @interface MyTarget{ String value();}可以這樣用: @MyTarget("aaa") public void doSomething() { System.out.println("hello world"); } 註解@Target也是用來修飾註解的元註解,它有一個屬性ElementType也是枚舉類型,值為:ANNOTATION_TYPE CONSTRUCTOR FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE如@Target(ElementType.METHOD) 修飾的註解表示該註解只能用來修飾在方法上。@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyTarget{ String value() default "hahaha";}如把@MyTarget修飾在類上,則程式報錯,如:@MyTargetpublic class MyTargetTest註解大都用在開發架構中吧,好了有關註解就學習那麼多了,謝謝。
Java注釋@interface的用法【轉】