JAVA基礎加強_註解


註解(Annotation)
概念:
註解相當於一種標記,在程序中加了註解就等於爲程序打上了某種標記,沒加,則等於沒有某種標記,以後,javac編譯器,開發工具和其他程序可以用反射來了解你的類及各種元素上有無何種標記,看你有什麼標記,就去幹相應的事。標記可以加在包,類,字段,方法,方法的參數以及局部變量上。

4個 基本的Annotation(存在於java.lang包下)
@Override
@Deprecated
@Suppress Warnings
@Safe Varargs(JAVA7新增的)

@Override:限定重寫父類方法
@Override就是用來指定方法覆蓋的,他可以強制一個子類必須覆蓋父類的方法。

注意:@Override只能作用於方法,不能作用於其他程序元素

@Deprecated:標示已過時
@Deprecated用於標示某個程序元素(類、方法等)已過時,當其他程序使用已過時的類、方法時,編譯器將會給出警告。

@SuppressWarnings:抑制編譯器警告
@SuppressWarnings指示被該Annotation修飾的程序元素(以及該程序元素中的所有子元素)取消顯示指定的編譯器警告。


存在於java.lang.Annotation中的元註解用於修飾其他的Annotation定義
@Documented 
@Inherited 
@Retention 
@Target

@Retention
@Retention只能用於修飾一個Annotation定義,用於指定被修飾的Annotation可以保留多長時間。
@Retention包含一個RetentionPolicy類型的value成員變量,所以使用@Retention時必須爲該Value成員變量指定值。

Value成員變量的值有3個:
RetentionPolicy.CLASS:編譯器將把Annotation記錄在class文件中。當運行java程序時,JVM不在保留Annotation。這是默認值。
RetentionPolicy.RUNTIME:編譯器將把Annotation記錄在class文件中。當運行時java程序,JVM也會保留Annotation,程序可以通過反射獲取該Annotation信息。
RetentionPolicy.SOURCE:Annotation只保留在源代碼中,編譯器直接丟棄Annotation。

@Target
@Target也只能修飾一個Annotation定義,它用於指定被修飾的Annotation能用於修飾哪些程序單元。

其value成員變量的值:
ElementType.ANNOTATON_TYPE:指定該策略的Annotation只能修飾Annotation。
ElementType.CONSTRUCTOR:指定該策略的Annotation只能修飾構造函數
ElementType.FIELD:指定該策略的Annotation只能修飾成員變量
ElementType.LOCAL_VARIABLE:指定該策略的Annotation只能修飾局部變量
ElementType.METHOD:指定該策略的Annotation只能修飾方法
ElementType.PACKAGE:指定該策略的Annotation只能修飾包
ElementType.PARAMETER:指定該策略的Annotation可以修飾參數
ElementType.TYPE:指定該策略的Annotation可以修飾類、接口(包括註釋類型)或枚舉

@Documented
@Documented用於指定被該元Annotation修飾的Annotation類將被javadoc工具提取成文檔,如果定義Annotation類時使用了@Documented修飾,則所有使用該Annotation秀水的程序元素的API文檔中將會包含該Annotation說明。

@Inherited
@Inherited元Annotation指定被他修飾的Annotation將具有繼承性——如果某個類使用了@Annotation(定義該Annotation時使用了@Inherited修飾)修飾,則其子類將自動被@Annotation修飾

註解的應用結構圖:


基礎應用:使用反射技術獲取Annotation信息
前提:元註解Retention的value值必須是RetentionPolicy.RUNTIME
代碼示例:
註解代碼:
package cn.itheima.Annotation;

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

@Retention(RetentionPolicy.RUNTIME)//元註解
public @interface MyAnnotation
{

}
獲取註解信息:
package cn.itheima.Annotation;

@MyAnnotation//將註解應用到類上
public class AnnotationTest
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// 獲取註解信息
		//判斷AnnotationTest的字節碼文件中是否存在MyAnnotation註解
		if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class))
		{
			//輸出註解信息
			//注意:元註解Retention的value值必須是RetentionPolicy.RUNTIME否則返回值爲null
			System.out.println((MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class));
		}
		
	}
}

總結:
使用到的方法體系
java.lang.Class
|--boolean isAnnotationPresent(Class annotationclass)  如果指定類型的註釋存在於此元素上,則返回 true,否則返回 false。
|--<A extends Annotation> A getAnnotation(Class<A> annotationClass)   如果存在該元素的指定類型的註釋,則返回這些註釋,否則返回 null。

 註解生命週期的三個階段:1,源文件 2,class文件 3,內存中的字節碼
@Override     --> SOURCE
@Deprecated--> RUNTIME
@Suppress Warnings-->SOURCE


爲註解增加基本屬性

什麼是註解的屬性
一個註解相當於一個胸牌,如果你胸前貼了胸牌,就是傳智播客的學生,否則,就不是。如果還想區分出是傳智播客哪個班的學生,這時候可以爲胸牌在增加一個屬性來進行區分。加了屬性的標記效果爲:@MyAnnotation(color="red")

定義基本類型的屬性和應用屬性:
在註解類中增加String color();
@MyAnnotation(color="red")

用反射方式獲得註解對應的實例對象後,再通過該對象調用屬性對應的方法
MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
可以認爲上面這個@MyAnnotation是MyAnnotaion類的一個實例對象

爲屬性指定缺省值:
String color() default "yellow";

value屬性:
String value() default "zxx"; 
如果註解中有一個名稱爲value的屬性,且你只想設置value屬性(即其他屬性都採用默認值或者你只有一個value屬性),那麼可以省略value=部分,例如:@MyAnnotation("lhm")。

數組類型的屬性
int [] arrayAttr() default {1,2,3};
@MyAnnotation(arrayAttr={2,3,4})
如果數組屬性中只有一個元素,這時候屬性值部分可以省略大括

枚舉類型的屬性
EnumTest.TrafficLamp lamp() ;
@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)

註解類型的屬性:
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
@MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )
可以認爲上面這個@MyAnnotation是MyAnnotaion類的一個實例對象,同樣的道理,可以認爲上面這個@MetaAnnotation是MetaAnnotation類的一個實例對象,調用代碼如下:
MetaAnnotation ma =  myAnnotation.annotationAttr();
System.out.println(ma.value());

代碼示例:
枚舉:
package cn.itheima.Annotation;

public enum Lamp
{
	GREEN,RED,YELLOW;
}
增加屬性的註解:
package cn.itheima.Annotation;

public @interface MetaAnnotation
{

	String value();

}
註解:
package cn.itheima.Annotation;

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,ElementType.METHOD})
public @interface MyAnnotation
{
	//定義類型
	String color();
	String value();
	int[] arr();
	Lamp lamp();
	MetaAnnotation metaAnnotation();
}
測試代碼
//將註解應用到類上
@MyAnnotation(color = "green", value = "123",arr = {1,2,3},lamp = Lamp.RED,metaAnnotation = @MetaAnnotation("Hello"))
public class AnnotationTest
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// 獲取註解信息
		//判斷AnnotationTest的字節碼文件中是否存在MyAnnotation註解
		if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class))
		{
			//輸出註解信息
			//注意:元註解Retention的value值必須是RetentionPolicy.RUNTIME否則返回值爲null
			MyAnnotation annotation = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
			System.out.println(annotation);
			//基本類型
			System.out.println(annotation.color());
			//value值
			System.out.println(annotation.value());
			//數組類型
			System.out.println(annotation.arr().length);
			//枚舉類型
			System.out.println(annotation.lamp());
			//註解類型
			System.out.println(annotation.metaAnnotation());
		}

			
	}
}

注意註解中各類型的定義方法和賦值方法


發佈了57 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章