Java 注解Annotation

cwf8 10年前

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