自定义注解是Java高阶语言特性,在各种三方框架中经常能见到它们的身影。自定义注解能够使你编写高可维护性、更具灵活性的代码。在这篇博文中,我们将探索Java的自定义注解世界,并学习如何有效地利用它们
1.什么是自定义注解
注解Annotation是以元数据的形式在Java5中引入,它添加到Java代码里,如Java类(class)、方法、属性甚至是其他注解。它们给代码提供了额外的信息,在三方框架和库用于生成代码、执行验证或在运行时应用某些行为时进行使用。自定义注解顾名思义,是你自己定义的注解。它们允许你根据自己的需求,扩展Java现有的注解集合。
2.Java自带注解
Java常见的一些注解有,@Override:用于检查方法是否是重写父类的方法。@FunctionalInterface:用于检查接口是否是函数式接口。@Deprecated:用于标注方法已经过时,不推荐使用。除了这些注解还有其他注解,
3.什么是元注解
用于其他注解的注解称为元注解。在java.lang.annotation中定义了几种元注解类型。
- @Retention
- @Documented
- @Target
- @Inherited
- @Repeatable
3.1@Retention注解
RetentionPolicy.SOURCE:注解只保留在源码中,编译器会丢弃掉
RetentionPolicy.CLASS:注解将保留在.class文件里,但在运行时不会保留
RetentionPolicy.RUNTIME:注解将保留在.class文件中,并且jvm会保留,可以通过反射读取
如果注解类型声明中不存在Retention注解,则Retention默认为 RetentionPolicy.CLASS。
3.2 @Documented注解
带有该类型的注解会被javadoc和其他类似工具进行文档化。
3.3 @Target注解
此注解用来进行限定可以使用该注解的Java元素类型,它有以下几种类型
ElementType.TYPE:允许被修饰的注解作用在类、接口(包括注解类型)和枚举上
ElementType.FIELD:允许作用在属性字段上(包括枚举常量)
ElementType.METHOD:允许作用在方法上
ElementType.PARAMETER:允许作用在方法参数上
ElementType.CONSTRUCTOR:允许作用在构造器上
ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
ElementType.ANNOTATION_TYPE:允许作用在注解上
ElementType.PACKAGE:允许作用在包上
ElementType.TYPE_PARAMETER 应用于类型变量的声明语句前。
ElementType.TYPE_USE 应用于所有使用类型的任何语句(如:泛型,类型转换等)
3.4 @Inherited注解
如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解
- 接口用上个@Inherited修饰的注解,其实现类不会继承这个注解
- 父类的方法用了@Inherited修饰的注解,子类也不会继承这个注解
3.5 @Repeatable注解
Java8 之前禁止对同样的注解类型声明多次,用这个元注解表示申明的注解是可以重复的,举个例子
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(AnoType.class)
public @interface AnoType{
String value() default "value";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnoType{
AnoType[] value();
}
public class AnnotationClass {
@AnoType("hello")
@AnoType("world")
public void test(String var1, String var2) {
System.out.println(var1 + " " + var2);
}
}
4.如何定义一个自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TaskCondition {
boolean index() default false;
}
如上面的代码TaskCondition就是一个自定义注解,自定义注解是@interface关键词开头。加上元注解进行搭配
5.如何获取自己定义的注解
从字段上获取自定义注解:
public class MyClass implements MyInterface {
@MyAnnotation("My Class")
private int myField;
@Override
public void myMethod() {}
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Field field = MyClass.class.getDeclaredField("myField");
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value());
}
}
从方法上获取自定义注解:
public class MyClass {
@MyAnnotation("Hello World")
public void myMethod() {}
public static void main(String[] args) throws NoSuchMethodException {
Method method = MyClass.class.getMethod("myMethod");
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value());
}
}