1.注解说明:
Java5开始,java开始对元数据的支持,也就是Annotation(注解)。元数据:metadata文件夹中 描述数据的数据.
所有的Annotation都是java.lang.annotation.Annotation 接口的子接口,所以Annotation是一种特殊的接口
2.使用注解需要注意,必须有三方参与才有意义:
a):得有注解标签本身;
b):被贴的程序元素(类,字段,构造器,方法,参数上,包上等);
c):由第三方的程序使用反射的手段来赋予注解特殊的功能(也是Java代码).
3.JDK自带的注解:
Java5提供的:
@Override限定覆写父类方法,只能运用于方法上.
@Deprecated 标记已过时,标识为不推荐使用的.在Java5之前,我们使用文档注释来表示该功能:
@SuppressWarings 抑制编译器发出的多种警告,自欺欺人的做法. @SuppressWarings(value="all"):可以运用到变量,方法,类上.
Java7提供的:
@SafeVarargs 抑制堆污染警告(Java7开始出现的) 当方法使用了可变参数和泛型参数,可能导致堆污染.如:Arrays.asList(); 方法的注解
4.元注解(描述注解的注解,用来限定注解可以贴在哪些程序元素上,还可以指定注解存在的周期.):
@Retention: 表示注解可以保存在哪一个代码时期. 保存的时期的值,封装在RetentionPolicy枚举类中:
注意:一般的,自定义的注解,使用RUNTIME.(使用反射赋予注解功能)
SOUECE:注解只能存在于源文件中,一旦编译,在字节码中就消失了.>
CLASS:(缺省),注解可以存在于源文件和字节码文件中,一旦加载进JVM,在JVM中就消失了.
RUNTIME:注解可以存在于源文件,字节码文件,JVM中.
@Target: 表示注解可以贴在哪些位置(类,方法上,构造器上等等).位置的常量封装在ElementType枚举类中:
ElementType.ANNOTATION_TYPE只能修饰Annotation
ElementType.CONSTRUCTOR只能修饰构造方法
ElementType.FIELD只能修饰字段(属性),包括枚举常量
ElementType.LOCAL_VARIABLE只能修饰局部变量
ElementType.METHOD只能修饰方法
ElementType.PACKAGE只能修饰包(极少使用)
ElementType.PARAMETER只能修饰参数
ElementType.TYPE只能修饰类,接口,枚举
@Documented: 使用@Documented标注的标签会保存到API文档中.
比如:@Deprecated注解使用了@Documented元注解,所以被@Deprecated所标注的成员,都会保持到API文档中.
@Inherited: @Inherited标注的标签可以被子类所继承.
5.注解使用格式:
定义注解:使用@interface.</br>
@Retention(设置存在的时期)
@Target(设置贴在哪些元素之上)
public @interface 注解名称{
注解中的成员,抽象方法---->属性.
数据类型 方法名() default 默认值;
}
6.代码演示:
a定义注解
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Vip {
//注解属性值有一个值并且这个值的名字是 value的时候,在使用注解赋值的时候可以省略赋值参数
//注解属性是数组的是,赋值时候要用{}。如 name={"aa","bb"}
//注解属性有默认值的时候,使用注解的时候可以不赋值
String value();
String[] name();
int age() default 18;
String num() default "998";
}
b使用注解
@Vip(value="aaa", name={"bb","cc"})
public class Student{
@Vip(value="xxxx", name={"zzz","yyy"})
private String name;
@Vip(value="pppp",name={"qqq","www"})
public void study(){
}
}
c赋予注解特殊定义
public static void main(String[] args) {
//判断类是否包含Vip注解
if(Student.class.isAnnotationPresent(Vip.class)){
Vip vip=Student.class.getAnnotation(Vip.class);
System.out.println("@#@"+vip.value());
System.out.println("@#@"+vip.name());
System.out.println("@#@"+vip.age());
System.out.println("@#@"+vip.num());
//获取所有的注解
Annotation[] annotations=Student.class.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation.annotationType().equals(Vip.class)){
System.out.println("@@@111");
}
}
}
//获取类的所有方法
Method[] methods=Student.class.getDeclaredMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(Vip.class)){
Vip vip=method.getAnnotation(Vip.class);
System.out.println("@#@"+vip.value());
System.out.println("@#@"+vip.name());
System.out.println("@#@"+vip.age());
System.out.println("@#@"+vip.num());
}
}
//获取类所有的字段
Field[] fields=Student.class.getDeclaredFields();
for (Field field : fields) {
if(field.isAnnotationPresent(Vip.class)){
Vip vip=field.getAnnotation(Vip.class);
System.out.println("@#@"+vip.value());
System.out.println("@#@"+vip.name());
System.out.println("@#@"+vip.age());
System.out.println("@#@"+vip.num());
}
}
}