首先明確一個(gè)概念:
annotation=注解 comment=注釋 不要混淆了
a) Override注解表示子類要重寫(override)父類的對(duì)應(yīng)方法。
舉例:OverrideTest.java
package com.shengsiyuan.annotation;public class OverrideTest{@Override//該注解表示該類重寫了父類的方法public String toString(){return "This is OverrideTest";}public static void main(String[] args){OverrideTest test = new OverrideTest();System.out.println(test);}}
b) Deprecated注解表示方法是不建議被使用的。
舉例:DeprecatedTest.java
package com.shengsiyuan.annotation;public class DeprecatedTest{@Deprecated//該注解表示這個(gè)方法是廢棄的,不建議被使用的public void doSomething(){System.out.println("do something!");}public static void main(String[] args){DeprecatedTest test = new DeprecatedTest();test.doSomething();// Date date = new Date();//// System.out.println(date.toLocaleString());}}
c) SuppressWarnings注解表示抑制警告。
舉例:SuppressWarningsTest.java
package com.shengsiyuan.annotation;import java.util.Date;import java.util.Map;import java.util.TreeMap;public class SuppressWarningsTest{@SuppressWarnings({"unchecked", "deprecation"})//該注解表示一些警告會(huì)被壓制住//unchecked表示不對(duì)集合沒有使用泛型進(jìn)行警告//deprecation表示不對(duì)已經(jīng)廢棄的方法的使用進(jìn)行警告public static void main(String[] args){Map map = new TreeMap();map.put("hello", new Date());System.out.println(map.get("hello"));Date date = new Date();System.out.println(date.toLocaleString());}}
關(guān)于自定義注解
自定義注解:當(dāng)注解中的屬性名為value時(shí),在對(duì)其賦值時(shí)可以不指定屬性的名稱而直接寫上屬性值即可;除了value以外的其他值都需要使用name=value這種賦值方式,即明確指定給誰(shuí)賦值。
舉例如下:
(1)先定義一個(gè)注解
package com.shengsiyuan.annotation;public @interface AnnotationTest{//注解里定義屬性要在屬性后面加一個(gè)括號(hào)String[] value1() default "hello";//有一個(gè)默認(rèn)值helloEnumTest value2(); //注解里面的值也可定義為枚舉類型}enum EnumTest{Hello, World, Welcome;}
注意:當(dāng)一個(gè)接口繼承Annotation接口時(shí),該接口依然只是一個(gè)接口,還不是注解類型,
要定義注解類型只有一種方式:通過@interface關(guān)鍵字,除此之外別無他法。
另外,Annotation本身也只是一個(gè)接口,并不是注解類型(可以查看API文檔有 Annotation這個(gè)接口)
(2)引用上面的注解
package com.shengsiyuan.annotation;@AnnotationTest(value2 = EnumTest.Welcome)public class AnnotationUsage{@AnnotationTest(value1 = {"world", "ABCD"}, value2 = EnumTest.World)public void method(){System.out.println("usage of annotation");}public static void main(String[] args){AnnotationUsage usage = new AnnotationUsage();usage.method();}}
1.關(guān)于@Retention這個(gè)注解
Retention翻譯成中文是“保留”的意思,RetentionPolicy是“保留策略”。
簡(jiǎn)要描述:指示注解類型的注解要保留多久。如果注解類型聲明中不存在 Retention 注解,則保留策略默認(rèn)為 RetentionPolicy.CLASS。
每一個(gè)Retention都要給他一個(gè)RetentionType,RetentionType是一個(gè)枚舉類型(具體可以查看API文檔),它有3種取值:SOURCE,CLASS,RUNTIME,區(qū)別如下:
(a)SOURCE:表示該注解只會(huì)存在于JAVA源文件中,不會(huì)編譯到class文件里面去,更不會(huì)在運(yùn)行期通過反射的方式獲 取到。
(b)CLASS:表示該注解會(huì)隨著JAVA源代碼一起編譯到class文件里面去,但不會(huì)在運(yùn)行期通過反射的方式獲取到。
(c)RUNTIME:表示該注解會(huì)隨著JAVA源代碼一起編譯到class文件里面去,并且會(huì)在運(yùn)行期通過反射的方式獲取到。
請(qǐng)看一個(gè)示例:
首先定義一個(gè)注解:
package com.shengsiyuan.annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;//注解也可以修飾注解,該注解修飾下面自定義的注解,通過設(shè)定//RetentionPolicy的值為RUNTIME表示該自定義的注解會(huì)被編//譯到CLASS文件當(dāng)中,而且可以在運(yùn)行期通過反射的方式獲取到(具體請(qǐng)查看一遍API文檔,很有必要?。〡Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation{String hello() default "shengsiyuan";String world();}
然后定義一個(gè)類,用這個(gè)Annotation去修飾
package com.shengsiyuan.annotation;@MyAnnotation(hello = "beijing", world = "shanghai")public class MyTest{//一個(gè)方法可以被多個(gè)注解所修飾。@MyAnnotation(hello = "tianjin", world = "shangdi")@Deprecated@SuppressWarnings("unchecked")public void output(){System.out.println("output something!");}}
接著定義一個(gè)類,并通過反射相關(guān)API去獲得自定義注解的相關(guān)信息
package com.shengsiyuan.annotation;import java.lang.annotation.Annotation;import java.lang.reflect.Method;//該類拿到修飾MyTest里方法的Annotationpublic 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[]{});//能夠進(jìn)入到if語(yǔ)句里面來說明MyAnnotation的RetentionPolicy的值為Runtime(為什么請(qǐng)查API文檔!)if(method.isAnnotationPresent(MyAnnotation.class)){method.invoke(myTest, new Object[]{});MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);String hello = myAnnotation.hello();String world = myAnnotation.world();System.out.println(hello + ", " + world);}//只會(huì)得到Myannotation和Deprecated兩個(gè)Annotation,因?yàn)橹挥羞@兩個(gè)Annotation的RetentionPolicy//的值為Runtime,只有RetentionPolicy的值為Runtime才會(huì)在運(yùn)行期通過反射相關(guān)API拿到Annotation的相關(guān)信息。Annotation[] annotations = method.getAnnotations();for(Annotation annotation : annotations){System.out.println(annotation.annotationType().getName());}}}
2.關(guān)于@Target這個(gè)注解(建議去讀一讀API文檔,介紹的很詳細(xì))
簡(jiǎn)要描述:指示注解類型所適用的程序元素的種類。如果注解類型聲明中不存在 Target 元注解,則聲明的類型可以用在任一程序元素上。
每一個(gè)Target都要給他一個(gè)ElementType,ElementType是一個(gè)枚舉類型(具體可以查看API文檔),它有8種取值:SOURCE,CLASS,RUNTIME,區(qū)別如下:
(a)ANNOTATION_TYPE:表示該注解可以去修飾另外一個(gè)注解
(b)COUNSTRUCTOR:表示該注解可以修飾構(gòu)造方法
(c)FIELD:表示該注解可以修飾成員變量
(d)LOCAL_VARIABLE:表示該注解可以修飾局部變量
(e)METHOD:表示該注解可以修飾普通方法
(f)PACKAGE:表示該注解可以修飾包
(g)PARAMETER:表示該注解可以修飾方法參數(shù)
(h)TYPE:表示該注解可以修飾類、接口(包括注解類型)或枚舉聲明
請(qǐng)看示例:
package com.shengsiyuan.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Target;@Target(ElementType.METHOD)//表示該自定義注解只能用于修飾方法public @interface MyTarget{String value();}
接著定義一個(gè)類:
package com.shengsiyuan.annotation;public class MyTargetTest{@MyTarget("hello")public void doSomething(){System.out.println("hello world");}}
當(dāng)把該自定義的注解放到方法上面后編譯器不報(bào)錯(cuò)時(shí),說明我們的實(shí)驗(yàn)是成功的(不需要寫main方法進(jìn)行測(cè)試)
對(duì)以上2個(gè)注解的總結(jié):Retention與Target都是注解,Retention與RetentionPolicy搭配,Target與ElementType搭配。
3.關(guān)于@Documented(了解就行)
不多做描述,請(qǐng)看示例:
package com.shengsiyuan.annotation;import java.lang.annotation.Documented;@Documented //當(dāng)一個(gè)注解被@Documented 修飾后表示被該注解修飾的對(duì)象(類或方法或其他)在生成JAVA DOC文檔時(shí),該注解會(huì)被加到修飾的對(duì)象的上面public @interface DocumentedAnnotation{String hello();}
然后用該注解去修飾某個(gè)方法
package com.shengsiyuan.annotation;public class DocumentedTest{@DocumentedAnnotation(hello = "welcome")public void method(){System.out.println("hello world");}}
當(dāng)對(duì)DocumentedTest所在的包或工程生成JAVA DOC文檔的時(shí)候,會(huì)發(fā)現(xiàn)自定義的注解會(huì)出現(xiàn)在method方法的上面
聯(lián)系客服