介紹
java 1.5引入了注解(annotation),注解類似注釋,不同的是注解除了提供代碼說明,
還能實現(xiàn)程序的邏輯功能,在很多java框架中都得到了廣發(fā)的應(yīng)用贵涵。
元注解
元注解的作用就是負(fù)責(zé)注解其他注解。Java5.0定義了4個標(biāo)準(zhǔn)的meta-annotation類型恰画,它們被用來提供對其它 annotation類型作說明宾茂。
- @Target 修飾了注解使用范圍 可以是類(TYPE),方法(METHOD),字段(FIELD),構(gòu)造函數(shù)(CONSTRUCTOR),參數(shù)(PARAMETER)拴还,局部變量(LOCAL_VARIABLE)刻炒,包(PACKAGE)
- @Retention 修飾了注解存在的時間 SOURCE 只在源碼中出現(xiàn),CLASS 只在Class文件可以看見 RUNTIME 運行時也可以看見
- @Documented 用來修飾注解是否出現(xiàn)在API中
- @Inherited 是否會被子類繼承 注解正常只出現(xiàn)在父類 子類不繼承 加上這個標(biāo)記 子類也能獲得注解
示例代碼
給類付上額外的信息
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ClassAnno {
String value() default "類注解";
}
@ClassAnno("Test類")
public class Test {
}
public class Main {
public static void main(String ...args){
ClassAnno classAnno=Test.class.getAnnotation(ClassAnno.class);
if(classAnno!=null){
System.out.println(classAnno.value());
}
}
}
測試方法
- 去掉Test類上的注解 查看結(jié)果
- 去掉Test類上注解的值 查看結(jié)果
注解應(yīng)用 驗證類
一個驗證接口
/**
* 驗證接口
* @param <T> 值類型
* @param <A> 注解類型
*/
public interface Validator<T,A> {
/**
* 驗證方法
* @param value 值
* @param anno 注解
* @return 錯誤信息 如果是null表示無錯誤
*/
String validate(T value,A anno);
}
實現(xiàn)一個注解和驗證接口實現(xiàn)類的綁定
/**
* 綁定注解和驗證類
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidatorBind {
/**
* 驗證類
* @return
*/
Class validator();
}
實現(xiàn)一個接受驗證結(jié)果的類
/**
* 驗證結(jié)果
*/
public class ValidatorResult {
/**
* 錯誤信息
*/
private String message;
/**
* 字段名稱
*/
private String fieldName;
/**
* 字段路徑
*/
private String fieldPath;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getFieldPath() {
return fieldPath;
}
public void setFieldPath(String fieldPath) {
this.fieldPath = fieldPath;
}
}
實現(xiàn)一個驗證工具
public class ValidatorUtil {
/**
* 獲取所有字段
* @param clz
*/
public static List<Field> getAllField(Class clz){
Field[] declaredFields = clz.getDeclaredFields();
Field[] fields=clz.getFields();
List<Field> fieldList=new ArrayList<>(fields.length+declaredFields.length);
for(int i=0;i<declaredFields.length;i++){
declaredFields[i].setAccessible(true);
fieldList.add(declaredFields[i]);
}
for(int i=0;i<fields.length;i++){
fieldList.add(fields[i]);
}
return fieldList;
}
/**
* 驗證對象的某個字段是否符合規(guī)則
* @param field 字段
* @param object 對象
* @param results 錯誤結(jié)果存儲
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
private static boolean validatorField(Field field, Object object,List<ValidatorResult> results) throws IllegalAccessException, InstantiationException {
Annotation[] annos = field.getAnnotations();
for(Annotation annotation:annos){
ValidatorBind validatorBind=annotation.annotationType().getAnnotation(ValidatorBind.class);
if(validatorBind!=null){
Validator validator= (Validator) validatorBind.validator().newInstance();
String msg=validator.validate(field.get(object),annotation);
if(msg!=null){
ValidatorResult validatorResult=new ValidatorResult();
validatorResult.setFieldName(field.getName());
validatorResult.setMessage(msg);
results.add(validatorResult);
return false;
};
}
}
return true;
}
/**
* 驗證對象
* @param object
* @return 錯誤結(jié)果合集
*/
public static List<ValidatorResult> validator(Object object){
//返回結(jié)果
List<ValidatorResult> results=new ArrayList<>();
Class clz=object.getClass();
List<Field> fields=getAllField(clz);
for(Field field:fields){
try {
validatorField(field,object,results);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
return results;
}
}
上面一個驗證框架就完成了
下面是增加驗證功能
增加一個NotNull驗證
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@ValidatorBind(validator = NotNullValidator.class)
@interface NotNull {
String msg() default "不能為空";
}
實現(xiàn)類
/**
* 驗證Object不是NULL
*/
public class NotNullValidator implements Validator<Object,NotNull> {
/**
* 驗證不能為NULL
* @param value 值 Object類型
* @param anno 注解 NotNull注解
* @return
*/
@Override
public String validate(Object value, NotNull anno) {
if(value==null){
return anno.msg();
}
return null;
}
}
增加正則驗證
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@ValidatorBind(validator = PatternValidator.class)
public @interface Pattern {
String regexp() default "";
String msg() default "不符合正則規(guī)則";
}
實現(xiàn)正則驗證規(guī)則
public class PatternValidator implements Validator<String,Pattern> {
@Override
public String validate(String value, Pattern anno) {
String regexp=anno.regexp();
if(!RegExp.test(regexp,value)){
return anno.msg();
}
return null;
}
}
測試類
class A {
@NotNull
@Pattern(regexp = "^\\d+$",msg = "必須是純數(shù)字")
String name;
}
public class Main {
public static void main(String ...args){
A a=new A();
a.name="asd";
List<ValidatorResult> list = ValidatorUtil.validator(a);
if(list.isEmpty()){
System.out.println("通過驗證");
}else{
for(ValidatorResult result:list) {
System.out.println(result.getFieldName()+' '+result.getMessage());
}
}
}
}