java --註解

#1.什麼是註解?
註解也叫元數據(用來描述數據的數據),它用來對某些元素進行說明/註釋等。
註解是一個接口,程序能夠經過反射來獲取指定元素的Annotaion,而後經過Annotation對象來獲取註解裏面的元數據。
#2.註解的所用?
2.1 建立文檔,經過在代碼裏標識註解生成[doc文檔]。
2.2 跟蹤代碼的依賴性,配置依賴信息可使用xml文檔與註解兩種形式 。
2.3 執行編譯時檢查,如@override放在方法前,若是這個方法不是重寫父類的方法,則編譯報錯。
#3.註解的分類
3.1 標記註解,Annotation類型沒有成員變量,例如Override。
3.2 單值註解。
3.3 完整註解。
#4.註解的分類
4.1 jdk自帶註解
@Override:重寫父類中方法。
@Deprecated:代表該類、方法不建議使用。
@SuppressWarnings:忽略警告。
4.2 元註解
4.3 自定義註解
#5.java提供的註解
@Target、@Retention、@Documented、@Inherited
5.1 @Target
@Target說明了Annotation修飾對象的範圍,Annotaion能夠用於packages、types(類、接口、枚舉、Annotation類型)、types成員(方法、構造方法、成員變量、枚舉值)。
做用:描述該註解使用的範圍
取值(ElementType)有:
1.TYPE:類、接口(包括註解)、枚舉聲明
2.FIELD:域變量(包括枚舉常量)
3.METHOD:方法
4.PARAMETER:描述參數
5.CONSTRUCTOR:構造器
6.LOCAL_VARIABLE:局部變量
7.ANNOTATION_TYPE:註解類型
8.PACKAGE:包
舉例java

@Target(ElementType.METHOD)
public @interface Override {
}

說明:Override這個註解只能用於方法上面。
5.2 @Retention
@Retention定義了該註釋保留多長時間,默認是RetentionPolicy.CLASS,即在class文件中有效。
做用:描述該註解的生命週期
取值(RetentionPolicy)有:
1.SOURCE:在源文件中有效,編譯時被丟棄
2.CLASS:在類文件中有效,編譯時被記錄,在運行時被丟棄
3.RUNTIME:在運行時有效
舉例api

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
	public String name() default "fieldName";
}

說明:Column註解可用於變量上面,在運行時有效。Column註解的屬性值是運行時,所以這樣的註解能夠經過反射獲取到該註解的屬性值。
5.3 @Documented
做用:生成javadoc文檔,@Documented註解是一個標記註解,沒有成員。
5.4 @Inherited
@Inherited是一個標記註解,@Inherited表示它修飾的對象類型是能夠被繼承的。
#6.自定義註解
使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation接口。在自定義註解時,不能繼承其它的註解或接口。@interface用來申明一個註解,其中每個方法其實是聲明瞭一個配置參數。方法的名稱就是參數參數的名稱,返回值類型就是參數類型。
以下是自定義註解
1.水果名稱註解ide

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitType {
	String value() default "";
}

2.水果顏色註解工具

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
	enum Color{BULE,RED,GREEN;}
	
	Color fruitColor() default Color.BULE;
}

3.水果提供商註解ui

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {

	//供應商編號
	public int id() default 1;
	//供應商名稱
	public String name() default "";
	//供應商地址
	public String address() default "";
}

#7.註解處理器
定義了註解,若是不使用,那也沒用。
使用註解,必須建立註解處理器,java中利用反射機制,能夠幫咱們構造註解處理器。
java使用Annotation接口來表示程序元素前面的註解,java在reflect包下新增了AnnotatedElement接口,該接口能夠接受註解的程序元素,該接口主要的實現類
Class、Constructor、Field(類的成員變量)、Method、Package
java.lang.reflect包下主要是一些實現反射功能的工具類,該包提供了反射api來讀取運行時Annotation信息。
AnnotatedElement接口是全部程序元素(Class、Constructor、Field(類的成員變量)、Method、Package)的父接口,因此程序經過反射獲取了整個類的AnnotatedElement對象以後,程序就能夠調用該對象以下四個方法來訪問Annotation信息:
getAnnotation(Class<T> annotationClass):返回程序元素上指定類型的註解,若是註解不存在,則返回null
getAnnotations:返回程序元素上全部的註解
getDeclaredAnnotations:返回程序元素上全部的註解,忽略父級註解
isAnnotationPresent(Class<? extends Annotation> annotationClass):判斷程序元素上是否包含指定類型的註解(@Target、@Retention、@Documented、@Inherited ),存在則返回true,不然返回false。 註解處理器以下.net

/**
 * 註解處理器
 */
public class FruitUtil {
	
	public static void getFruitUtil(Class<?> clazz)
	{
		//定義變量
		String strFruitName = "水果名稱:";
		String strFruitColor = "水果顏色:";
		String strFruitProvider = "供應商信息:";
		
		//getDeclaredFields:獲取clazz類裏面全部的屬性
		Field[] fields = clazz.getDeclaredFields();
		
		//循環註解
		for(Field field:fields)
		{
			//若是FruitType上包含註解
			if (field.isAnnotationPresent(FruitType.class)) {
				//獲取該程序元素
				FruitType fruitName = (FruitType)field.getAnnotation(FruitType.class);
				//獲取該程序元素的註解值
				strFruitName = strFruitName+fruitName.value();
				//打印註解值
				//備註:實際工程中,這裏根據拿到的註解值作相關的業務
				System.out.println(strFruitName);
			}else if (field.isAnnotationPresent(FruitColor.class)) {
				FruitColor fruitColor = (FruitColor)field.getAnnotation(FruitColor.class);
				strFruitColor = strFruitColor+fruitColor.fruitColor();
				System.out.println(strFruitColor);
			}else if (field.isAnnotationPresent(FruitProvider.class)) {
				FruitProvider fruitProvider = (FruitProvider)field.getAnnotation(FruitProvider.class);
				strFruitProvider = strFruitProvider+"供應商編號:"+
											fruitProvider.id()+";"+
											"供應商名稱"+
											fruitProvider.name()+";"+
											"供應商地址"+
											fruitProvider.address();
				System.out.println(strFruitProvider);
			}
		}
	}
}

採用如上方法拿到了註解值,而後能夠作相關的處理操做。可是相關的操做,不能影響主業務。code

相關文章
相關標籤/搜索