java用 @interface Annotation{ } 定義一個(gè)注解 @Annotation,一個(gè)注解是一個(gè)類。
@Override,@Deprecated,@SuppressWarnings為常見的3個(gè)注解。
注解相當(dāng)于一種標(biāo)記,在程序中加上了注解就等于為程序加上了某種標(biāo)記,以后,
JAVAC編譯器,開發(fā)工具和其他程序可以用反射來了解你的類以及各種元素上有無任何標(biāo)記,看你有什么標(biāo)記,就去干相應(yīng)的事。
注解@Override用在方法上,當(dāng)我們想重寫一個(gè)方法時(shí),在方法上加@Override,當(dāng)我們方法
的名字出錯(cuò)時(shí),編譯器就會(huì)報(bào)錯(cuò),如圖:
注解@Deprecated,用來表示某個(gè)類的屬性或方法已經(jīng)過時(shí),不想別人再用時(shí),在屬性和方法
上用@Deprecated修飾,如圖:
注解@SuppressWarnings用來壓制程序中出來的警告,比如在沒有用泛型或是方法已經(jīng)過時(shí)的時(shí)候,
如圖:
注解@Retention可以用來修飾注解,是注解的注解,稱為元注解。
Retention注解有一個(gè)屬性value,是RetentionPolicy類型的,Enum RetentionPolicy是一個(gè)枚舉類型,
這個(gè)枚舉決定了Retention注解應(yīng)該如何去保持,也可理解為Rentention 搭配 RententionPolicy使用。RetentionPolicy有3個(gè)值:CLASS RUNTIME SOURCE
用@Retention(RetentionPolicy.CLASS)修飾的注解,表示注解的信息被保留在class文件(字節(jié)碼文件)中當(dāng)程序編譯時(shí),但不會(huì)被虛擬機(jī)讀取在運(yùn)行的時(shí)候;
用@Retention(RetentionPolicy.SOURCE )修飾的注解,表示注解的信息會(huì)被編譯器拋棄,不會(huì)留在class文件中,注解的信息只會(huì)留在源文件中;
用@Retention(RetentionPolicy.RUNTIME )修飾的注解,表示注解的信息被保留在class文件(字節(jié)碼文件)中當(dāng)程序編譯時(shí),會(huì)被虛擬機(jī)保留在運(yùn)行時(shí),
所以他們可以用反射的方式讀取。RetentionPolicy.RUNTIME 可以讓你從JVM中讀取Annotation注解的信息,以便在分析程序的時(shí)候使用.
- package com.self;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
-
- @Retention(RetentionPolicy.RUNTIME)
- public @interface MyTarget
- { }
- 定義個(gè)一注解@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));
- }
- }
- }
- 上面程序打?。?span>@com.self.MyTarget(),如果RetentionPolicy值不為RUNTIME,則不打印。
-
- @Retention(RetentionPolicy.SOURCE )
- public @interface Override
-
- @Retention(RetentionPolicy.SOURCE )
- public @interface SuppressWarnings
-
- @Retention(RetentionPolicy.RUNTIME )
- public @interface Deprecated
- 由上可以看出,只有注解@Deprecated在運(yùn)行時(shí)可以被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;
- }
- 上面程序中,定義一個(gè)注解@MyAnnotation,定義了6個(gè)屬性,他們的名字為:
- hello,world,array,lamp,lannotation,style.
- 屬性hello類型為String,默認(rèn)值為gege
- 屬性world類型為String,沒有默認(rèn)值
- 屬性array類型為數(shù)組,默認(rèn)值為2,4,5,6
- 屬性lamp類型為一個(gè)枚舉,沒有默認(rèn)值
- 屬性lannotation類型為注解,默認(rèn)值為@TestAnnotation,注解里的屬性是注解
- 屬性style類型為Class,默認(rèn)值為String類型的Class類型
-
- 看下面例子:定義了一個(gè)MyTest類,用注解@MyAnnotation修飾,注解@MyAnnotation定義的屬性都賦了值
- @MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)
- public class MyTest
- {
- @MyAnnotation(lannotation=@TestAnnotation(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); //調(diào)用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數(shù)組的長(zhǎng)度
- System.out.println(myAnnotation.lannotation().value()); //打印屬性lannotation的值
- System.out.println(myAnnotation.style());
- }
- //得到output方法上的所有注解,當(dāng)然是被RetentionPolicy.RUNTIME修飾的
- Annotation[] annotations = method.getAnnotations();
- for (Annotation annotation : annotations)
- {
- System.out.println(annotation.annotationType().getName());
- }
- }
- }
- 上面程序打?。?nbsp;
- have annotation
- output something!
- gege, shanghai
- 3
- baby
- class java.lang.String
- com.heima.annotation.MyAnnotation
- java.lang.Deprecated
-
- 如果注解中有一個(gè)屬性名字叫value,則在應(yīng)用時(shí)可以省略屬性名字不寫。
- 可見,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解屬性值,屬性名字是value,
- 屬性的返回類型是RetentionPolicy,如下:
- public @interface MyTarget
- {
- String value();
- }
- 可以這樣用:
- @MyTarget("aaa")
- public void doSomething()
- {
- System.out.println("hello world");
- }
-
- 注解@Target也是用來修飾注解的元注解,它有一個(gè)屬性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修飾在類上,則程序報(bào)錯(cuò),如:
- @MyTarget
- public class MyTargetTest
- 注解大都用在開發(fā)框架中吧,好了有關(guān)注解就學(xué)習(xí)那么多了,謝謝。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。