1.自定義註解html
import java.lang.annotation.*; @Documented @Target(ElementType.FIELD) @Inherited @Retention(RetentionPolicy.RUNTIME ) public @interface MyAnno { /** * 是否能爲null * @return */ boolean isCanNull() default true; /** * 是否能爲空字符串 * @return */ boolean isCanEmpty() default true; /** * 是否能爲0 * @return */ boolean isCanZero() default true; }
2.使用註解:java
public class Mouse { @MyAnno(isCanNull=true) private String name; @MyAnno(isCanNull = false,isCanZero = false) private int age; @MyAnno(isCanNull = false) private String address; @MyAnno(isCanZero = false) private double money; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
3.得到註解的值並對其判斷web
package com.vweb.util; import com.vweb.webapp.Mouse; import com.vweb.webapp.MyAnno; import com.vweb.webapp.TestUtil; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.Arrays; import java.util.List; public class IntactCheckUtil { public static boolean check(Object obj){ // list = Arrays.asList(AnnotationParsing.class.getClassLoader().loadClass(((Class)obj).getClass().getName()).getDeclaredFields()); List<Field> list = Arrays.asList(obj.getClass().getDeclaredFields()); for(int i=0;i<list.size();i++){ Field field = list.get(i); if(field.isAnnotationPresent(MyAnno.class)){//是否使用MyAnno註解 for (Annotation anno : field.getDeclaredAnnotations()) {//得到全部的註解 if(anno.annotationType().equals(MyAnno.class) ){//找到本身的註解 if(!((MyAnno)anno).isCanNull()){//註解的值 if(TestUtil.getFieldValueByName(field.getName(),obj)==null){ throw new RuntimeException("類:"+Mouse.class+"的屬性:"+field.getName()+"不能爲空,實際的值:"+TestUtil.getFieldValueByName(field.getName(),obj)+",註解:field.getDeclaredAnnotations()"); } } if(!((MyAnno)anno).isCanEmpty()){ if(TestUtil.getFieldValueByName(field.getName(),obj).equals("")){ throw new RuntimeException("類:"+Mouse.class+"的屬性:"+field.getName()+"不能爲空字符串,實際的值:"+TestUtil.getFieldValueByName(field.getName(),obj)+",註解:field.getDeclaredAnnotations()"); } } if(!((MyAnno)anno).isCanZero()){ if(TestUtil.getFieldValueByName(field.getName(),obj).toString().equals("0") || TestUtil.getFieldValueByName(field.getName(),obj).toString().equals("0.0")){ throw new RuntimeException("類:"+Mouse.class+"的屬性:"+field.getName()+"不能爲空字符0,實際的值:"+TestUtil.getFieldValueByName(field.getName(),obj)+",註解:field.getDeclaredAnnotations()"); } } } } } } return true; } }
備註:註解各參數的使用(如下內容來自互聯網http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html)數組
@Target:app
@Target說明了Annotation所修飾的對象範圍:Annotation可被用於 packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)。在Annotation類型的聲明中使用了target可更加明晰其修飾的目標。webapp
取值(ElementType)有:工具
1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述局部變量
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述參數
7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明ui
@Retention定義了該Annotation被保留的時間長短:某些Annotation僅出如今源代碼中,而被編譯器丟棄;而另外一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另外一些在class被裝載時將被讀取(請注意並不影響class的執行,由於Annotation與class在使用上是被分離的)。使用這個meta-Annotation能夠對 Annotation的「生命週期」限制。this
取值(RetentionPoicy)有:spa
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在運行時有效(即運行時保留)
@Documented:
該屬性用於描述其它類型的annotation應該被做爲被標註的程序成員的公共API,所以能夠被例如javadoc此類的工具文檔化。Documented是一個標記註解,沒有成員。
@Inherited:
@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的。若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。
注意:@Inherited annotation類型是被標註過的class的子類所繼承。類並不從它所實現的接口繼承annotation,方法並不從它所重載的方法繼承annotation。
當@Inherited annotation類型標註的annotation的Retention是RetentionPolicy.RUNTIME,則反射API加強了這種繼承性。若是咱們使用java.lang.reflect去查詢一個@Inherited annotation類型的annotation時,反射代碼檢查將展開工做:檢查class和其父類,直到發現指定的annotation類型被發現,或者到達類繼承結構的頂層。
自定義註解:
使用@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",後加小括號.例:下面的例子FruitName註解就只有一個參數成員。
簡單的自定義註解和使用註解實例: