一、概念:
注解相当于一种标记,在某一个程序上加了注解就相当于为这部分程序打了标记,该标记用来表示该程序段的特征或形态。我们可以通过javac编译器、开发工具、程序等使用反射机制来处理这些标记,对不同的标记去做一些不同的事。注解可以加在包、类、方法、方法参数、字段、局部变量等上面。
二、jdk默认提供注解:
在JDK5.0以后默认提供了三个常用的注解类:
1)、@Override:只能作用于方法之上,用来告诉别人这个方法是改写父类的一个方法。
2)、@Deprecated:用于说明该程序元素已过时,可以作用于程序中任何元素之上,用 @Deprecated 注释的程序元素,不鼓励程序员使用,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
3)、@SuppressWarnings:用于关闭编译器提示的警告信息。
三、自定义注解:

1.元注解说明:
元注解
:就是专门用来定义注解的注解,主要作用就是用于约束自定义注解的功能。比如注解只能用在方法上、类上或字段上等。
/*
* JDK自带的元注解有:@Target,@Retentio,@Documented,@Inherited
*
* @Target:指示该注解类型用于什么元素之上,如果注解没有添加@Target标示,则可以作用于任一程序元素上,如果加上了@Target注解类型约束,则编译器会强制检查作用于程序元素上的限制。
* 可选的ElementType注解类型包括:
* ElementType.ANNOTATION_TYPE:只能作用于注解类型上
* ElementType.CONSTRUCTOR:只能作用于构造方法上
* ElementType.FIELD:只能作用于字段上(包括枚举常量)
* ElementType.LOCAL_VARIABLE:只能作用于局部变量上
* ElementType.METHOD:只能作用于方法上
* ElementType.PACKAGE:只能作用于包上
* ElementType.PARAMETER:只能作用于方法参数声明上
* ElementType.TYPE:只能作于类、接口、枚举、注解上
*
* @Retention:指示在什么级别保留注解信息。如果注释类型声明中不存在Retention,则保留策略默认为 RetentionPolicy.CLASS。
* 可选的RetentionPolicy保留级别包括:
* RetentionPolicy.SOURCE:仅保留在源代码中,javac编译完后,会丢弃注解。不会保存在编译好的class文件上。
* RetentionPolicy.CLASS:保留在源代码和class文件中,jvm加载class字节码文件时,不会加载注解。
* RetentionPolicy.RUNTIME:即保留在源代码和class文件中,也会被jvm加载到内存当中,所以可通过反射的方式读取注解信息。
*
* @Documented:标示了此注解的元素,注释将成为注解元素公共API的一部分。
*
* @Inherited:指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。
*/
2.下面看一个具体例子:
a.创建一个注解:
package com.gyb.hello;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 注解使用说明:
1、自定义的Annotation,隐式的继续自java.lang.Annotation,所以不能在继承其它的类或接口。
2、在Annotation中声明的属性方法只能是public的,或者默认不加访问修饰符,(默认是public abstract)。
3、方法的返回值类型只限8种基本类型byte、int、short、long、float、double、char、boolean,和String、enum、annotation、Class,以及这些类型的数组。
4、方法不能有参数
5、方法不能抛异常
*/
@Target({ElementType.TYPE, ElementType.METHOD})//定义注解作用在类、接口等类型上和方法上
@Retention(RetentionPolicy.RUNTIME)//定义保留级别到运行时
public @interface MyAnnotation {
/*
* 这里可以声明多种类型的属性方法以供我们实际应用中使用
*/
String value() default "gyb"; //为属性设置默认值
String color();
int[] arr() default {1,2,3,4,5,6};
//返回值类型为注解类型的属性
//XXXXAnnotation annotationAttr();
}
b.注解使用和测试类:
package com.gyb.hello;
import java.lang.reflect.Method;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation.ANONYMOUS;
@MyAnnotation(color="red",arr={8,9}) //另外两个属性已有默认值,这边可以只对color属性设值。
public class AnnotationTest {
@MyAnnotation(color="blue",value="hehe")
public void getInfo(){
System.out.println("hello annotation...");
}
public static void main(String args[]){
//判断某个类中是否存在某个注解
if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
//通过反射获得类级别的注解信息
MyAnnotation annotation = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(annotation.color());//输出red
System.out.println(annotation.value());//输出默认值gyb
System.out.println(annotation.arr().length);//输出设置的数组长度2
}
//通过反射获得方法级别的注解信息(getInfo()方法)
Method m[] = AnnotationTest.class.getMethods();
for(Method method : m){
if(method.isAnnotationPresent(MyAnnotation.class)){//判断某个方法中是否存在某注解
MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);
System.out.println(annotation.color());//输出blue
System.out.println(annotation.value());//输出hehe
System.out.println(annotation.arr().length);//输出默认数组长度6
}
}
}
测试结果:
red
gyb
2
blue
hehe
6
通告上面的例子我们对注解有了一个基本的了解,注解应该是以后的一个趋势吧,目前spring、springmvc、struts2等开源框架中都引入了注解,注解的使用将会使我们的xml配置文件大大缩减,而且能够在一定程度上增加开发效率。