java 自定義注解以及獲得注解的值


1.自定義注解

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.使用注解:

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.獲得注解的值並對其判斷

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:

   @Target說明了Annotation所修飾的對象范圍:Annotation可被用於 packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)。在Annotation類型的聲明中使用了target可更加明晰其修飾的目標。

    取值(ElementType)有:

    1.CONSTRUCTOR:用於描述構造器
    2.FIELD:用於描述域
    3.LOCAL_VARIABLE:用於描述局部變量
    4.METHOD:用於描述方法
    5.PACKAGE:用於描述包
    6.PARAMETER:用於描述參數
    7.TYPE:用於描述類、接口(包括注解類型) 或enum聲明

@Retention定義了該Annotation被保留的時間長短:某些Annotation僅出現在源代碼中,而被編譯器丟棄;而另一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另一些在class被裝載時將被讀取(請注意並不影響class的執行,因為Annotation與class在使用上是被分離的)。使用這個meta-Annotation可以對 Annotation的“生命周期”限制。

  取值(RetentionPoicy)有:

    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注解就只有一個參數成員。

  簡單的自定義注解和使用注解實例:

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM