`

自定义以及使用Annotation

阅读更多

1. 什么是Annotation

Annotation是元数据(metadata)的一种格式,它提供了关于程序但是却与程序本身无关的数据。并且,注解与被注解的代码并没有直接的关系。(译自于Java Tutorial)

 

2. Annotation的作用

  • Information for the compiler --注解可以被编译器用来探测错误或者压制警告。
  • Compile-time and deployment-time processing -- 软件工具可以运行注解的信息来生成代码,XML 文件等等。

  • Runtime processing -- 一些注解还可以在运行期来检测。

其实,简单的说,Annotation就是一种标识符,然后通过这种特殊的标识符可以在程序的不同时期(编译器或运行期)做一些特殊的处理,这样以这种很优美的方式来达到自己想要的效果。

 

3. Annotation的分类

3.1 Meta-Annotations

这类注解主要是至以下四个:@Documented  @Retention  @Target @Inherited,这是JDK定义好的,主要是用来使用在注解上,用来对注解进行描述的注解。

3.2  Maker Annotation

这类注解主要是用来做一个声明,这是一类特殊的注解,他们没有成员(members)

 

这是目前搜集到的两类,其他的以后将会继续的进行补充。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

也请各位DN指教

 

4. 自定义Annotation

4.1 一个非常简单的demo

这一部分的内容在网上有大量的资料,下面是一个最简单的Annotation:

 

public @interface Author {
	String name() default "";
}

 

 

@Retention ,指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。 其取值为参考RetentionPolicy

@Target,指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。其驱逐参考:ElementType

 

4.2 相对复杂的demo

 

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
   Class expected();
}

 这里声明了@Target 和 @Retention,这样就不能随意去在不同的时期和元素上使用了,只能够被使用在方法上,并且只能够保留到运行期。

 

 

5. 使用自定义的Annotation

上面也说了,自定义个Annotation这样的例子在网上很多,很多比这里的例子都还要好,而且,自定义Annotation也是非常简单的。不过对于使用自定义的Annotation的例子就不多了,而且也是相对来说比较复杂。

其实,使用自定义的Annotation主要用到的就是Java的反射机制来获取到Annotation的信息或者属性等等,然后自己再根据获取到的有关信息后进行处理。

下面是一个完整的自定义Annotation,使用,解析的全部代码:

 

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test {
   String info() default "";
}

class Annotated {
   @Test(info = "AWESOME")
   public void foo(String myParam) {
      System.out.println("This is " + myParam);
   }
}

class TestAnnotationParser {
   public void parse(Class clazz) throws Exception {
      Method[] methods = clazz.getMethods();
      for (Method method : methods) {
         if (method.isAnnotationPresent(Test.class)) {
            Test test = method.getAnnotation(Test.class);
            String info = test.info();
            if ("AWESOME".equals(info)) {
                System.out.println("info is awesome!");
                // try to invoke the method with param
                method.invoke(
                   Annotated.class.newInstance(),
                   info
                );
            }
         }
      }
   }
}

public class Demo {
   public static void main(String[] args) throws Exception {
      TestAnnotationParser parser = new TestAnnotationParser();
      parser.parse(Annotated.class);
   }
}

 此部分主要参考与:http://isagoksu.com/2009/creating-custom-annotations-and-making-use-of-them/

 

 

6. 总结

对于Annotation的定义比较简单易学,但是对于具体的使用的话,则需要根据具体的应用需求场景来确定注解的定义以及解析的时机。

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics