注解分类

注解分为标准注解和元注解

标准注解

标准注解有以下几种:

  • @Override:对覆盖超类中的方法进行标注,如果被标注的方法并没有实际覆盖超类中的方法,编译器会发错错误警告。
  • @Deprecated:对不鼓励使用或已过时的方法进行标注,当开发人员对这些被标注的方法进行调用时,会显示该方法已过时的提示信息。
  • @SuppressWarnings:选择性的取消特定代码段中的警告。
  • @SafeVarargs:JDK 7 新增的注解,用来声明使用了可变长度参数的方法,其在与泛型类一起使用时会出现类型安全问题。

元注解

元注解是用来标注注解的注解,在注解定义时使用。有以下几种:

  • @Targe:标注所修饰的对象范围。
  • @Inherited:表示注解可以被继承。
  • @Documented:表示注解应该被JavaDoc工具记录。
  • @Retention:用来声明注解的保留策略。
  • @Repeatable:JDK 8 新增的注解,允许一个注解在同一声明类型(类、属性或方法)中多次使用。

下面重点介绍下@Targe注解及@Retention注解:

@Targe注解

其中@Targe注解的取值是一个ElementType类型的数值。这里有以下几种取值,对应不用的对象范围。

  • ElementType.TYPE:声明类、接口或枚举类型。
  • ElementType.FIELD:声明成员变量。
  • ElementType.METHOD:声明方法。
  • ElementType.PARAMETER:声明参数。
  • ElementType.CONSTRUCTOR:声明构造方法。
  • ElementType.LOCAL_VARIABLE:声明局部变量。
  • ElementType.ANNOTATION_TYPE:声明注解类型。
  • ElementType.PACKAGE:声明包。
  • ElementType.TYPE_PARAMETER:声明参数类型。
  • ElementType.TYPE_USE:使用类型。
  • ElementType.MODULE:声明模块。

@Retention注解

@Retention注解有3种类型,分别表示不同级别的保留策略。

  • RetentionPolicy.SOURCE:源码级注解。注解信息只保留在.java源码中。源码在编译后,注解信息被丢弃,不会保留在.class中。
  • RetentionPolicy.CLASS:编译时注解。注解信息会保留在.java源码以及.class中。当运行Java程序时,JVM会丢弃该注解信息,不会保留在JVM中。
  • RetentionPolicy.RUNTIME:运行时注解。当运行Java程序时,JVM也会保留该注解信息,可以通过反射获取该注解信息。

注解的定义和使用

基本定义和使用

定义新的注解类型使用@interface关键字,这与定义一个接口很像:

1
2
public @interface MyAnnotation {
}

定义完成后,就可以在程序中使用注解

1
2
3
@MyAnnotation
public class AnnotationTest {
}

注解成员变量的定义和使用

注解只有成员变量,没有方法。注解的成员变量在注解定义中以“无参的方法”形式来声明,其“方法名”定义了该成员变量的名字,其返回值定义了该成员变量的类型:

1
2
3
4
public @interface MyAnnotation {
String name();
int age();
}

上面的代码定义了nameage两个成员变量,使用该注解时就要给两个成员变量指定值:

1
2
3
@MyAnnotation(name = "droidYu",age = 0)
public class AnnotationTest {
}

也可以在定义成员变量时,用default关键字为其指定默认值:

1
2
3
4
public @interface MyAnnotation {
String name() default "droidYu";
int age() default 0;
}

在使用时就可以不进行赋值操作:

1
2
3
@MyAnnotation()
public class AnnotationTest {
}

定义成员变量时,有个一特殊的成员变量value,在使用时可以不用写 value = ,而直接传入value的值即可:

1
2
3
4
5
public @interface MyAnnotation {
String name() default "droidYu";
int age() default 0;
String value();
}
1
2
3
@MyAnnotation(value = "no value")
public class AnnotationTest {
}

此时value=可以省略:

1
2
3
@MyAnnotation("no value")
public class AnnotationTest {
}

使用元注解定义注解

定义注解时,还可以为注解添加元注解,例如使用@Target@Retention元注解来定义只能用来注解方法的运行时注解:

1
2
3
4
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMethod {
}

此时的MyMethod注解就只能标注在方法上,如果标注在类上,编译器就会提示错误警告,编译不能通过。

1
2
3
4
5
6
7
8
@MyAnnotation("no value")
@MyMethod //这里会报错,编译不能通过
public class AnnotationTest {
@MyMethod //正确的使用位置
public void method() {

}
}

示例代码已上传Github

关注我