注解是 java5 引入的特性,在代码中插入一种注释化的信息,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。注解也叫元数据(meta data)。这些注解信息可以在编译期使用预编译工具进行处理(pre-compiler tools),也可以在运行期使用 Java 反射机制进行处理。 它主要的作用有以下四方面:
一般注解可以分为三类:
、
- @Override
和
- @Deprecated
,分别用于标明重写某个方法、标明某个类或方法过时、标明要忽略的警告,用这些注解标明后编译器就会进行检查。
- @SuppressWarnings
、
- @Retention
、
- @Target
、
- @Inherited
,
- @Documented
用于标明注解被保留的阶段,
- @Retention
用于标明注解使用的范围,@Inherited 用于标明注解可继承,
- @Target
用于标明是否生成 javadoc 文档。
- @Documented
为什么在类、方法上加一个注解,就可以通过 getAnnotation() 获取到申明的注解的值? 比如:
- @Test("test")
- public class AnnotationTest {
- public void test(){
- }
- }
对于注解 test 就可以在运行时通过 AnnotationTest.class.getAnnotation(Test.class) 获取注解声明的值。
在 AnnotationTest 类被编译后,在对应的 AnnotationTest.class 文件中会包含一个 RuntimeVisibleAnnotations 属性,由于这个注解是作用在类上,所以此属性被添加到类的属性集上。即 Test 注解的键值对 value=test 会被记录起来。而当 JVM 加载 AnnotationTest.class 文件字节码时,就会将 RuntimeVisibleAnnotations 属性值保存到 AnnotationTest 的 Class 对象中,于是就可以通过 AnnotationTest.class.getAnnotation(Test.class) 获取到 Test 注解对象,进而再通过 Test 注解对象获取到 Test 里面的属性值。 这里可能会有疑问,Test 注解对象是什么?其实注解被编译后的本质就是一个继承 Annotation 接口的接口,所以
其实就是 "public interface Test extends Annotation",当我们通过 AnnotationTest.class.getAnnotation(Test.class) 调用时,JDK 会通过动态代理生成一个实现了 Test 接口的对象,并把将 RuntimeVisibleAnnotations 属性值设置进此对象中,此对象即为 Test 注解对象,通过它的 value() 方法就可以获取到注解值。
- @Test
注解可以通过作用的类型可分为:类注解、方法注解、参数注解、变量注解。
类注解 访问类注解的例子:
- Class aClass = TheClass.class;
- Annotation[] annotations = aClass.getAnnotations();
- for(Annotation annotation : annotations){
- if(annotation instanceof MyAnnotation){
- MyAnnotation myAnnotation = (MyAnnotation) annotation;
- System.out.println("name: " + myAnnotation.name());
- System.out.println("value: " + myAnnotation.value());
- }
- }
此方法获取到的是该类的所有注解,也可指定某一个类:
- Class aClass = TheClass.class;
- Annotation annotation = aClass.getAnnotation(MyAnnotation.class);
- if(annotation instanceof MyAnnotation){
- MyAnnotation myAnnotation = (MyAnnotation) annotation;
- System.out.println("name: " + myAnnotation.name());
- System.out.println("value: " + myAnnotation.value());
- }
Spring 中的
即是如此。
- @Service``@Controller
方法注解
- public class TheClass {
- @MyAnnotation(name="someName", value = "Hello World")
- public void doSomething(){}
- }
获取方法对象的指定注解:
- Method method = ... // 获取方法对象
- Annotation annotation = method.getAnnotation(MyAnnotation.class);
- if(annotation instanceof MyAnnotation){
- MyAnnotation myAnnotation = (MyAnnotation) annotation;
- System.out.println("name: " + myAnnotation.name());
- System.out.println("value: " + myAnnotation.value());
- }
SpringMVC 中的
即是如此。
- @RequestMapping
参数注解 方法的参数也可以添加注解:
- public class TheClass {
- public static void doSomethingElse(
- @MyAnnotation(name="aName", value="aValue") String parameter){
- }
- }
访问注解:
- Method method = ... //获取方法对象
- Annotation[][] parameterAnnotations = method.getParameterAnnotations();
- Class[] parameterTypes = method.getParameterTypes();
- int i=0;
- for(Annotation[] annotations : parameterAnnotations){
- Class parameterType = parameterTypes[i++];
- for(Annotation annotation : annotations){
- if(annotation instanceof MyAnnotation){
- MyAnnotation myAnnotation = (MyAnnotation) annotation;
- System.out.println("param: " + parameterType.getName());
- System.out.println("name : " + myAnnotation.name());
- System.out.println("value: " + myAnnotation.value());
- }
- }
- }
Mybatis 中的
即是如此
- @Param
变量注解 使用注解:
- public class TheClass {
- @MyAnnotation(name="someName", value = "Hello World")
- public String myField = null;
- }
获取注解:
- Field field = ...//获取方法对象</pre>
- <pre>
- Annotation annotation = field.getAnnotation(MyAnnotation.class);
- if(annotation instanceof MyAnnotation){
- MyAnnotation myAnnotation = (MyAnnotation) annotation;
- System.out.println("name: " + myAnnotation.name());
- System.out.println("value: " + myAnnotation.value());
- }
Spring 中的
即是如此。
- @Inject``@Resource
参考资料: 注解机制及其原理 Java Reflection(八): 注解
来源: http://www.cnblogs.com/aheizi/p/7070896.html