java注解


注解含义

个人理解就是一种带信息的标签, 即元数据,描述数据的数据, 这种数据一般不能独立运行,需要借助外部的代码或者工具才能发挥作用。使用关键字@interface定义一个注解类,本文主要用作快速熟悉的笔记

元注解

用来定义注解的基本注解

  1. @Retention, 指定生命周期,源代码中,字节码文件中,程序时JVM中
  • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
  • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
  • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们
  1. @Documented, 生成javadoc时,该注解会被包含
  2. @Target, 作用范围
  • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  • ElementType.CONSTRUCTOR 可以给构造方法进行注解
  • ElementType.FIELD 可以给属性进行注解
  • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
  • ElementType.METHOD 可以给方法进行注解
  • ElementType.PACKAGE 可以给一个包进行注解
  • ElementType.PARAMETER 可以给一个方法内的参数进行注解
  • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
  1. @Inherited, 是否可继承
    Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}

@Test
public class A {}

public class B extends A {}

注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解

  1. @Repeatable, 1.8引入, 可重复的意思, 该注解可以重复出现
# Persons是一个容器注解,容器注解是用来存放其他注解的地方,本身也是一个注解
public @interface Persons {
    Person[] value();
}

@Repeatable(Persons.class)
@interface Person{
    String role() default "";
}

@Person(role = "coder")
@Person(role = "PM")
@Person(role = "artist")
class SuperMan{
    
}

注解的属性,即成员变量

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

# 使用default定义默认值
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    int id();

    String msg() default "";

}

使用:

# 如果注解中只有一个成员变量value,则可以省略括号不写,不设置属性值
# 如果注解的属性设置了默认值,也可以不自定义属性值
@DemoAnnotation("demo")
public class Demo {

}

java预置的注解

  1. @Deprecated, 用于标记过时的注解
  2. @Override,标记该方法要复写父类中的方法
  3. @SuppressWarnings,组织警告,某些代码比如调用过时的方法是编译器会告警,使用该注解忽略编译器告警
  4. @SafeVarargs,参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。1.7新增
  5. @FunctionalInterface, 1.8新增,定义该接口为一个函数式接口

反射+注解

  1. isAnnotationPresent(),判断一个Class对象是否应用了某个注解
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
  1. getAnnotation, 指定注解类型,获取Class对象上的某个注解对象
public  A getAnnotation(Class annotationClass) {}
  1. getAnnotations, 获取所有的注解对象
public Annotation[] getAnnotations() {}

以上为作用与类上的注解的操作方法,其他作用域的注解类似

注解作用

  1. 提供信息给编译器:编译器可以利用注解来探测错误和告警信息
  2. 编译阶段时的处理:软件工具可以利用注解信息来生成代码,HTML文档或者其他相应的处理
  3. 运行时的处理:某些注解可以在程序运行的时候接受代码的提取