美文网首页
Java 注解基础

Java 注解基础

作者: Tinyspot | 来源:发表于2022-07-18 12:23 被阅读0次

1. 注解(Annotation)

  • JDK1.5 以后版本引入的一个特性
  • 可以被其他程序(比如:编译器)读取
  • 语法 @注释名

2. 内置注解

  • @Override
    • 标记重写父类方法
  • @Deprecated
    • 标记过时方法,表示不建议再使用
  • @SuppressWarnings
    • 抑制编译时的警告信息
    • 需要添加参数才能正常使用,例如 @SuppressWarnings("unchecked")

3. 元注解(meta-annotation)

  • 作用:注解其他注解
  • 定义了 4 个标准的 meta-annotation 类型,用来对其他类型作说明
    • @Target
    • @Retention
    • @Documented
    • @Inherited

3.1 @Target

  • Indicates the contexts in which an annotation type is applicable
public enum ElementType {
    TYPE,
    FIELD,
    METHOD,
    PARAMETER,
    CONSTRUCTOR,
    LOCAL_VARIABLE,
    ANNOTATION_TYPE,
    PACKAGE,
    TYPE_PARAMETER,
    TYPE_USE
}

3.2 @Retention

  • 描述注解的生命周期
  • SOURCE < CLASS < RUNTIME
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

public enum RetentionPolicy {
    // 保留在源码阶段,编译时被丢弃
    SOURCE,
    // 保留到编译进行时的class文件,但 JVM 加载class文件时候被遗弃
    CLASS,
    // 保留到程序运行时
    RUNTIME
}

3.3 @Documented

  • 将被记录在 javadoc 中

3.4 @Inherited

  • 子类可以继承父类的注解

4. 自定义注解

  • 定义注解用 @interface, 注解中只能包含属性
  • 里面的方法实际上是声明的属性,方法名称就是属性名称,返回值类型就是属性的类型
  • 若只有一个属性,一般名为 value
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EntryLog {
  // 属性 value
  String value() default "";
  String[] codes() default {};
}

若属性没有默认值,必须给注解赋值

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EntryLog {
  String value() default "";
  String[] codes();
}
// 需给注解赋值
@EntryLog(codes = {"1001", "1002"})

4.1 注解属性类型

  • 基本数据类型
  • String 类型
  • Class 类型
  • 枚举类型
  • 注解类型
  • 以上类型的一维数组

数组用 {} 来存储,当数组中只有一个值时可省略 {}

// 数组类型 String[] codes();
@EntryLog(codes = "1001")
@EntryLog(codes = {"1001", "1002"})

// 枚举数组类型  ElementType[] value();
@Target(ElementType.TYPE)
@Target({ElementType.TYPE, ElementType.METHOD})

4.2 反编译文件

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface EntryLog {
    int num() default 0;
    String value();
    // Class 类型
    Class<?> clazz();
    // 枚举类型
    CodeEnum codeEnum();
    // 注解类型
    DemoAnno demoAnno();
}
// 自动继承 java.lang.annotation.Annotation 接口
public interface EntryLog extends java.lang.annotation.Annotation {
  public abstract int num();
  public abstract java.lang.String value();
  public abstract java.lang.Class<?> clazz();
  public abstract com.example.concrete.CodeEnum codeEnum();
  public abstract com.example.concrete.DemoAnno demoAnno();
}
public interface Annotation {
  boolean equals(Object obj);
  int hashCode();
  String toString();
  Class<? extends Annotation> annotationType();
}

5. Spring 注解 @AliasFor

  • @AliasFor 用于声明注释属性别名

同一个注解中的两个属性互为别名
例如:@ComponentScan 注解中,value 和 basePackages 两个属性互为别名

public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};
}

跨注解的属性别名
例如:@Service#value的值可以映射到@Component#value

public @interface Service {
    @AliasFor(annotation = Component.class)
    String value() default "";
}
public @interface Component {
    String value() default "";
}

5.1 @SpringBootApplication 分析

public @interface SpringBootApplication {
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};

    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};
}

其他

相关文章

网友评论

      本文标题:Java 注解基础

      本文链接:https://www.haomeiwen.com/subject/zjoobltx.html