Java 注解Annotation

cwf8 9年前發布 | 17K 次閱讀 Java開發 annotation

1.創建一個注解

創建注解跟接口差不多,不過要在interface前加個@,可以用default在方法后面設置默認值,方法的返回類型包括基本類型、String、Class、enum、Annotation、以上類型數組。還要通過元注解(@Retention、@Target)定義其作用域、有效范圍。舉一個例子

 @Retention(RetentionPolicy.RUNTIME)    
    @Target({ElementType.ANNOTATION_TYPE})  
    public  @interface demo{
        public int value();//只有當value()是唯一需要使用時賦值,才可以這樣簡寫@demo(0)
        public String bbb() default "demo";
        public Class<?>  ccc() default Date.class;
        public ElementType ddd() default ElementType.TYPE;
        public Target eee() default @Target(value = { ElementType.TYPE });
        public char[] fff() default {'a','b'};
    }


2.元注解

元注解專職負責注解其他注解,共四種 @Target、@Retention、@Documented(將此注解包含在Javadoc中)、@Inherited(允許子類繼承父類),其實元注解跟泛型的通配符(?)差不多概念。先介紹下注解中用到的兩個枚舉參數

元注解@Target的參數

 public enum ElementType 
    {// 分別表示的作用范圍
        TYPE, // 類、接口、注解、泛型
        FIELD, // 域
        METHOD, // 方法
        PARAMETER, // 參數
        CONSTRUCTOR, // 構造方法
        LOCAL_VARIABLE, // 局部變量
        ANNOTATION_TYPE, // 應用于另一個注解上
        PACKAGE; // 包

      private ElementType() {}
    }

元注解@Retention的參數

 public enum RetentionPolicy
    {
      SOURCE,  //注解將被編譯器丟棄
      CLASS,   //保存在class文件中,VM 丟棄
      RUNTIME; //運行時保留,可通過反射獲取

      private RetentionPolicy() {}
    }

元注解@Target,表示該注解可以用在什么地方

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Target
{
  ElementType[] value();
}

元注解@Retention,注解的保存級別

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Retention
{
  RetentionPolicy value();
}

3. Java內置注解

@Override, 表示當前方法覆蓋父類中的方法,如果父類沒有該方法,編譯器錯誤

 //源碼
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {}

@Deprecated, 用這個標注方法,就會出現一條橫線,方法就基本廢了

//源碼
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.CONSTRUCTOR, 
             ElementType.FIELD, 
             ElementType.LOCAL_VARIABLE, 
             ElementType.METHOD, 
             ElementType.PACKAGE, 
             ElementType.PARAMETER, 
             ElementType.TYPE})
    public @interface Deprecated {}

@SuppressWarnings({"all"}) 消除警告用

 //源碼
    @Target({ElementType.TYPE, 
             ElementType.FIELD,
             ElementType.METHOD, 
             ElementType.PARAMETER, 
             ElementType.CONSTRUCTOR, 
             ElementType.LOCAL_VARIABLE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface SuppressWarnings {
        String[] value();// 這個數組的參數在下面
    }
關鍵字 用途
all to suppress all warnings
boxing to suppress warnings relative to boxing/unboxing operations
cast to suppress warnings relative to cast operations
dep-ann to suppress warnings relative to deprecated annotation
deprecation to suppress warnings relative to deprecation
fallthrough to suppress warnings relative to missing breaks in switch statements
finally to suppress warnings relative to finally block that don’t return
hiding to suppress warnings relative to locals that hide variable
incomplete-switch to suppress warnings relative to missing entries in a switch statement (enum case)
nls to suppress warnings relative to non-nls string literals
null to suppress warnings relative to null analysis
rawtypes to suppress warnings relative to un-specific types when using generics on class params
restriction to suppress warnings relative to usage of discouraged or forbidden references
serial to suppress warnings relative to missing serialVersionUID field for a serializable class
static-access o suppress warnings relative to incorrect static access
synthetic-access to suppress warnings relative to unoptimized access from inner classes
unchecked to suppress warnings relative to unchecked operations
unqualified-field-access to suppress warnings relative to field access unqualified
unused to suppress warnings relative to unused code


下面舉一個栗子

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;

public class AnnotationTest implements InvocationHandler {
    private Object obj;

    public AnnotationTest(Object obj) {
        this.obj = obj;
    }

    // ----------------定義注解--------------------
    // 讓此枚舉保留到運行時
    @Retention(RetentionPolicy.RUNTIME)
    // 用在方法上
    @Target({ ElementType.METHOD })
    public @interface Transaction {
        public boolean value() default true;
    }

    // ---------------定義一個接口------------------
    public interface IDao {
        @Transaction
        // 使用注解
        public void remove();
    }

    // --------------實現接口---------------------
    public static class DaoImpl implements IDao {
        Queue<String> queue;

        public DaoImpl(Queue<String> queue) {
            this.queue = queue;
        }

        @Override
        public void remove() {
            // 刪除報錯,要求回滾
            if (queue.peek().equals("stop")) {
                throw new NullPointerException();
            }
            System.err.println(queue.poll());
        }
    }

    // --------------得到代理類---------------------
    public Object getProxy() {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object paramObject, Method paramMethod,
            Object[] paramArrayOfObject) throws Exception {
        // 取方法上面的注解Transaction
        Transaction tran = paramMethod.getAnnotation(Transaction.class);
        boolean isTran = false;
        if (tran != null) {
            isTran = tran.value();// 判斷是否需要事務
        }
        Object rtnObj = null;
        try {
            if(isTran){System.err.println("啟動事務");}
            rtnObj = paramMethod.invoke(obj, paramArrayOfObject);
            if(isTran){System.err.println("提交事務");}
        }catch(Exception e){
            if(isTran){System.err.println("回滾事務");}
            throw e;
        }
        return rtnObj;
    }

    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<String>();
        Collections.addAll(queue, "1", "stop", "2");

        AnnotationTest test = new AnnotationTest(new DaoImpl(queue));
        IDao dao = (IDao) test.getProxy();
        try {
            while (queue.peek() != null) {
                dao.remove();
            }
        } catch (Exception e) {
            System.out.println("-----------------");
            for (String str : queue) {
                System.out.println(str);
            }
        }
    }
}

輸出:


啟動事務
1
提交事務
啟動事務
回滾事務
-----------------
stop
2

轉自:http://flyouwith.iteye.com/blog/2174420

 本文由用戶 cwf8 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!