java元注解详解

要想灵活应用自定义注解,首先来深入了解一下java元注解

  1. @Inherited
    • 类继承关系中,子类会继承父类中带有@Inherited的注解;
    • 接口继承关系中, 子接口不会继承父类接口的任何注解,不管有没有被@Inherited修饰
    • 类实现关系中,实现类不会继承任何接口的注解
  2. @Target
    @Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型),类型成员(方法、构造方法、成员变量、枚举值),方法参数和本地变量(如循环变量,catch参数),在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
    作用:用户描述注解的使用范围(即:被描述的注解可以用在什么地方)
    取值(ElementType)有:
类型 用途
CONSTUCTOR 用于描述构造器
FIELD 用于描述域
LOCAL_VARIABLE 用于描述局部变量
METHOD 用于描述方法
PACKAGE 用于描述包
TYPE 用于描述类,接口(包括注解类型)或enum声明

使用实例:

@Target(ElementType.TYPE)
public @interface Table {
    /**
     * 数据表名称注解,默认值为类名称
     * @return
     */
    public String tableName() default "className";
}
 
@Target(ElementType.FIELD)
public @interface NoDBColumn {
 	
}
注解Table可以用于注解类、接口(包括注解类型)或者enum声明,而注解NoDBColumn仅可用于注解类的成员变量
  1. @Retention
    该被保留的时间长短:某些Annotion仅出现在源码中,儿被编译器丢弃;而另一些被编译在class文件中;编译在class中的Annotion可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotion与class在使用上是被分离的)。使用这个meta-Annotation可以对Annotion的“生命周期” 限制。
    作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:别描述的注解在什么范围有效)
    取值(RetentionPoicy)有:
类型 作用 说明
SOURCE 在源文件中有效(即源文件保留) 仅出现在源代码中,而被编译器丢弃
CLASS 在class中有效(即在class保留) 被编译在class文件中
RUNTIME 在运行时有效(即运行时保留) 编译在class文件中

Retention meta-annotion类型有唯一的value作为成员,他的取值来自java.lang.annotionPolicy的枚举类型。具体实例如下;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}
Column注解的RetentionPolicy的属性值是RUNTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理
  1. @Documented
    该注解用于描述其他类型的annotion应该被作为被标注的程序成员的公共API,因为可以被例如,javadoc此类的工具文档化,Documented是一个标记注解,没有成员。
  2. @Native since 1.8
  3. @Repeatable since 1.8
    此注解为了解决注解不能再同一个地方重复使用而出现的。可以查看spring 定时任务注解
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    String CRON_DISABLED = "-";

    String cron() default "";

    String zone() default "";

    long fixedDelay() default -1L;

    String fixedDelayString() default "";

    long fixedRate() default -1L;

    String fixedRateString() default "";

    long initialDelay() default -1L;

    String initialDelayString() default "";
}

然后还需定义容器注解@Schedules,这样@Scheduled多个才可以正常使用

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Schedules {
    Scheduled[] value();
}

你可能感兴趣的:(java)