`
standalone
  • 浏览: 597963 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java的annotation

    博客分类:
  • java
阅读更多
从oracle的官方文档来学习annotations:

地址在: http://docs.oracle.com/javase/tutorial/java/javaOO/annotations.html

总结如下:

Annotations我理解就是程序的一些元数据,没有它程序也是ok的。它的主要用途体现在以下几个方面:

1. 替代以前简单的注释;

比如以前的注释可能是:
/*
author: Benjamin Franklin
date: 3/27/2010
*/


class My Class {}

用Annotations可以写成:
@Author(
   name = "Benjamin Franklin",
   date = "3/27/2010"
)
class MyClass() { }


再复杂一点的注释:

public class Generation3List extends Generation2List {

   // Author: John Doe
   // Date: 3/17/2002
   // Current revision: 6
   // Last modified: 4/12/2004
   // By: Jane Doe
   // Reviewers: Alice, Bill, Cindy

   // class code goes here

}


用Annotations:

@interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}

@ClassPreamble (
   author = "John Doe",
   date = "3/17/2002",
   currentRevision = 6,
   lastModified = "4/12/2004",
   lastModifiedBy = "Jane Doe",
   // Note array notation
   reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {

// class code goes here

}


其中,@interface是定义一个annotation的关键字,看上去像接口,其实不是。
如果要让@ClassPreamble的信息出现在javadoc生成的文档中,你必须给刚才定义的@ClassPreamble加上@Documented这个保留的annotation。

如下所示:
// import this to use @Documented
import java.lang.annotation.*;

@Documented
@interface ClassPreamble {

   // Annotation element definitions
   
}



2. 编译器保留的注解, 例如@Deprecated, @Override, 和 @SuppressWarnings.

@Deprecated意思是这个方法过时了,你最好不要再用了,你用我就给你来个warning;
@Override是提示你这个方法是覆盖了父类的一个方法;
@SuppressWarnings是告诉编译器这个方法可能会抛出warning,但你不要告诉我啦。

3. 在runtime用这些注解信息;
一般的用法在runtime的时候JVM不会load这些annotation信息,如果要让runtime知道,就要使用java.lang.annotation.RetentionPolicy了,这是个enum,有三个可选值,
分别是
  • CLASS:annotation会被记录在class文件里但不会被jvm load。
  • RUNTIME:记录在class文件里也会被jvm load,可以通过反射读取。
  • SOURCE:会被compiler丢弃。


具体看下面这个例子:

先定义一个annotation:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Test_Target {
    public String doTestTarget();
}


@Retention(RetentionPolicy.RUNTIME) 就是上面所说的在runtime时候我也要知道注解的信息。

@Target(ElementType.FIELD) 是指这个注解可以加在Field前面(所以你加到方法签名会编译不过的),java.lang.annotation.ElementType也是一个enum,其他可选择的值包括如下,不翻译了。

CONSTRUCTOR
          Constructor declaration
FIELD
          Field declaration (includes enum constants)
LOCAL_VARIABLE
          Local variable declaration
METHOD
          Method declaration
PACKAGE
          Package declaration
PARAMETER
          Parameter declaration
TYPE
          Class, interface (including annotation type), or enum declaration

定义了这个注解,看怎么在runtime时候访问它:

import java.lang.reflect.Field;

public class TestAnnotations {

   @Test_Target(doTestTarget="Hello World !")
   private String str;

   public static void main(String[] args) throws Exception {
      // We need to use getDeclaredField here since the field is private.
      Field field = TestAnnotations.class.getDeclaredField("str");
      Test_Target ann = field.getAnnotation(Test_Target.class);
      if (ann != null) {
         System.out.println(ann.doTestTarget());
      }
   }
}



注意在变量str前面使用了定义的注解,在main方法里通过反射获取到了注解中doTestTarget对应的值,所以输出是

Hello World !
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics