注解:一种通过在类、方法、或者属性等上使用类似@xxx的方式进行“打标签”,然后可以通过反射机制对标签的内容进行解析并进行相应处理的手段。
比如spring中的@Service注解,源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
元注解:
元注解就是java中默认实现的专门对注解进行注解的注解,一共5个。
1.@Target
此注解用于表示当前注解的使用范围,@Target({ElementType.TYPE})就代表着@Service这个注解是专门用来注解到类、接口、或者枚举类型上面的,当在方法上面加这个注解时,就会报错。可以看到注解位置是一个枚举类型,完整定义如下:
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
2.@Retention
此注解用于表示当前注解的生命周期,简单地说就是这个注解在什么时候起作用,如@Retention(RetentionPolicy.RUNTIME)就表示在程序运行期间依然有效,此时就可以通过反射拿到注解的信息,完整的枚举定义如下:
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
3.@Documented
当被此注解所注解时,使用javadoc工具生成文档就会带有注解信息。
4.@Inherited
此注解与继承有关,当A注解添加此注解后,将A注解添加到某类上,此类的子类就会继承A注解。如:
@Inherited
public @interface A{
}
@A
public class Parent{}
public class Son entends Parant{}//Son类继承了父类的A注解
5.@Repeatable
此注解顾名思义是拥有可以重复注解的能力。想象这样一个场景,我们需要定时执行某个任务,需要在每周一和周三执行,并且这个时间是可以灵活调整的,此时这个元注解就能派上用场:
@Repeatable(Schedules.class)
public @interface Schedule {
String date();
}
public @interface Schedules {
Schedule[] value();
}
@Schedule(date = "周一")
@Schedule(date = "周三")
public class Executor {
}
注意看到此元注解后面括号里内容,在这指定的类叫做容器注解,意思是保存这多个注解的容器,故我们创建一个@Schedules注解作为@Schedule的容器注解,容器注解必须含有一个名字为value,返回类型为需放入此容器的注解数组的属性。
本文参考:https://www.jb51.net/article/161279.htm