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