java自定義註解例子

java自定義註解

1.註解分類:

按運行機制分:

SOURCE源碼註解:註解只在源碼中存在,編譯成.class文件就不存在了
CLASS編譯時註解:註解在源碼和.class文件都存在,但運行時會被移除
(@Override,@Deprecated,@SuppressWarnings)
RUNTIME運行時註解:表示這個註解會保留到運行時,甚至還會影響運行邏輯
(@Autowired)

按來源分:

內置註解(@Override,@Deprecated,@SuppressWarnings)
第三方註解
自定義註解

2.元註解(註解的註解):

@Retention
定義註解的生命週期,可選值爲source、class、runtime
@Documented
文檔化註解,會被javadoc工具文檔化
@Inherited
註解是自動繼承的,想讓一個類和它的子類都包含某個註解,就可以使用它來修飾註解
@Target
Target通過ElementType來指定註解可使用範圍的枚舉集合
ElementType的用法

取值 註解使用範圍
METHOD 可用於方法上
TYPE 可用於類、接口、註解類型或枚舉類型
ANNOTATION_TYPE 可用於註解類型上(被@interface修飾的類型)
CONSTRUCTOR 可用於構造方法上
FIELD 可用於域上
LOCAL_VARIABLE 可用於局部變量上
PACKAGE 用於記錄java文件的package信息
PARAMETER 可用於參數上

3. 自定義註解例子:

使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation接口,由編譯程序自動完成其他細節。在定義註解時,不能繼承其他的註解或接口。@interface用來聲明一個註解,其中的每一個方法實際上是聲明瞭一個配置參數。方法的名稱就是參數的名稱,返回值類型就是參數的類型(返回值類型只能是基本類型、Class、String、enum)。可以通過default來聲明參數的默認值。

自定義註解格式:
public @interface 註解名{註解體}
1.所有基本數據類型(int,float,boolean,byte,double,char,long,short)
2.String類型
3.Class類型
4.enum類型
5.Annotation類型
6.以上所有類型的數組
Annotation類型裏面的參數該怎麼設定:
第一,只能用public或默認(default)這兩個訪問權修飾.例如,String value();這裏把方法設爲defaul默認類型;   
第二,參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和 String,Enum,Class,annotations等數據類型,以及這一些類型的數組.例如,String value();這裏的參數成員就爲String;  
第三,如果只有一個參數成員,最好把參數名稱設爲"value",後加小括號.例:下面的例子Name註解就只有一個參數成員。
註解元素的默認值
註解元素注意點:
註解元素必須有確定的值,要麼在定義註解的默認值中指定,要麼在使用註解時指定,非基本類型的註解元素的值不可爲null。因此, 使用空字符串或0作爲默認值是一種常用的做法。這個約束使得處理器很難表現一個元素的存在或缺失的狀態,因爲每個註解的聲明中,所有元素都存在,並且都具有相應的值,爲了繞開這個約束,我們只能定義一些特殊的值,例如空字符串或者負數,一次表示某個元素不存在,在定義註解時,這已經成爲一個習慣

1.Name.java(姓名註解)
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 
 * @description:姓名註解
 * @author: libl
 * @date: 2018年5月12日
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {
	String value() default "";
}

2.Gender.java(性別註解)
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @description:性別註解
 * @author: libl
 * @date: 2018年5月12日
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Gender {

	public enum GenderType {

		Male("男"), Female("女"), Other("中性");

		private String genderStr;

		private GenderType(String arg0) {
			this.genderStr = arg0;
		}

		@Override
		public String toString() {
			return genderStr;
		}
	}

	GenderType gender() default GenderType.Male;

}

3.Profile.java(基本資料註解)
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 
 * @description:基本資料註解
 * @author: libl  
 * @date: 2018年5月12日
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Profile {
	/**
     * ID
     *
     * @return
     */
    public int id() default -1;
 
    /**
     * 身高
     *
     * @return
     */
    public int height() default 0;
 
    /**
     * 籍貫
     *
     * @return
     */
    public String nativePlace() default "";
}

4.Person.java(使用註解)
/**
 * 
 * @description:使用自定義註解
 * @author: libl
 * @date: 2018年5月12日
 */
public class Person {
	@Name("李保磊")
	private String name;

	@Gender(gender = Gender.GenderType.Male)
	private String gender;

	@Profile(id = 1001, height = 180, nativePlace = "CN")
	private String profile;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getProfile() {
		return profile;
	}

	public void setProfile(String profile) {
		this.profile = profile;
	}
}

接口提供了以下四個方法來訪問Annotation的信息:
方法1:< T extends Annotation > T getAnnotation(Class< T > annotationClass): 返回改程序元素上存在的、指定類型的註解,如果該類型註解不存在,則返回null。
方法2:Annotation[] getAnnotations():返回該程序元素上存在的所有註解。
方法3:boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):判斷該程序元素上是否包含指定類型的註解,存在則返回true,否則返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在於此元素上的所有註釋。與此接口中的其他方法不同,該方法將忽略繼承的註釋。(如果沒有註釋直接存在於此元素上,則返回長度爲零的一個數組。)該方法的調用者可以隨意修改返回的數組;這不會對其他調用者返回的數組產生任何影響。

5.TestUtils.java(測試註解)
import java.lang.reflect.Field;

/**
 * 
 * @description:註解測試
 * @author: libl
 * @date: 2018年5月12日
 */
public class TestUtils {

	public static void main(String[] args) {
		TestUtils.getInfo(Person.class);
	}

	public static void getInfo(Class<?> clazz) {
		String name = "";
		String gender = "";
		String profile = "";
		Field fields[] = clazz.getDeclaredFields();
		for (Field field : fields) {
			if (field.isAnnotationPresent(Name.class)) {
				Name arg0 = field.getAnnotation(Name.class);
				name = name + arg0.value();
				System.out.println("name=" + name);
			}
			if (field.isAnnotationPresent(Gender.class)) {
				Gender arg0 = field.getAnnotation(Gender.class);
				gender = gender + arg0.gender().toString();
				System.out.println("gender=" + gender);
			}
			if (field.isAnnotationPresent(Profile.class)) {
				Profile arg0 = field.getAnnotation(Profile.class);
				profile = "[id=" + arg0.id() + ",height=" + arg0.height() + ",nativePlace=" + arg0.nativePlace() + "]";
				System.out.println("profile=" + profile);
			}
		}
	}
}


運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章