【Java进阶】开发中常用到注解,你知道它是什么玩意儿?

143 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、概述

位于 java.lang.annotation,接口 Annotation,出生于 JDK 1.5

我们使用注解以及注解能起到作用,需要有三方参与(注意:不是实习那个三方):

  • 注解标签本身
  • 被贴的程序元素(类、字段、构造器、方法、参数、包)
  • 由第三方的程序使用反射手段赋予注解特殊功能

简单记,就是自己、敌人以及打敌人的技能

二、常见的内置注解

@Override

  • 只能作用于方法
  • 作用:表示该方法是重写父类的方法,会进行验证

这家伙大伙肯定很熟了,写接口抽象方法的实现时,实现方法上面就有这么一个注解

@Deprecated

  • 可以作用于变量、方法、类
  • 作用:表示该作用域代码已过时,不建议使用,但能够使用

这家伙大伙应该也熟,比如Object#finalize()、Thread#stop()等等,我们在使用贴有这个注解的方法时,就会看到有一条删除线在这个方法上

@SuppressWarnings

  • 可以作用于变量、方法、类
  • 作用:抑制警告,只是看不到警告,不代表没有警告

有时候我们看到一些警告时,可以这么写但不建议这么写,但你偏要这么写时,就会出现黄色警告,这时用上这么一个注解,就舒服多了

image.png

image.png

@SafeVarargs

  • 作用于一个方法中同时出现可变参数和泛型
  • 作用:用于抑制对污染发出的警告,但问题依然存在

这个瞅瞅就好了

@FunctionalInterface

  • 作用于接口
  • 作用:用于检测该接口是否满足函数式接口的要求(接口中有且只有一个抽象方法)

这个是 JDK 1.8 增加的⼀个注解,用于检查接口是否符合要求,用法如下:

@FunctionalInterface 
public interface MyRunnable { 
    void run(); 
}

三、元注解

负责注解其它注解的注解称为元注解,用来提供对其它 annotation 类型作说明

分类

@Target

  • 用于描述注解的范围,即该注解能用在什么地方
  • 说明了 Annotation 所修饰的对象范围
  • ElementType
    • PACKAGE
    • TYPE 类、接口或枚举
    • ANNOTATION_TYPE 注解
    • CONSTRUCTOR 构造方法
    • METHOD 方法
    • FIELD 字段(包含枚举常量)
    • LOCAL_VARIABLE 局部变量(如循环变量、catch参数)
    • PARAMETER 方法参数

@Retention

  • 用于描述注解的生命周期,即注解保留时间的长短
  • RetentionPolicy
    • SOURCE:表示该注解只存在于源文件中,不会被编译到字节码中
    • CLASS:表示该注解会被编译到字节码中,但JVM不加载注解
    • RUNTIME:表示该注解会被编译到字节码中并进入JVM,可以通过反射读取

@Documented

  • 表示作为公共 API,能够被工具文档化
  • 标注注解,没有成员

其实也就是贴上这个注解的注解,在使用到具体的对象(类、方法等)上时,所生成的文档会显示出所贴的注解

@Inherited

  • 表示自动继承注释类型

四、注解的语法

使用@Interface声明一个注解,每一个方法实际上声明了一个配置参数,方法名为参数名,返回值类型为参数类型(只能是基本类型、Class、String、enum)

public @interface 注解名 {
    // 注解参数
}
注解参数支持的数据类型
  • 基本数据类型
  • String 类型
  • Class 类型
  • enum 类型
  • Annotation 类型
  • 以上所有类型的数组

注解元素必须有确定的值,可以在定义注解的默认值中指定,也可以使用注解时指定,非基本数据类型的注解元素的值不可为 null

五、自定义注解

使用@Interface标识,默认继承 java.lang.annotation.Annotation 接口,在定义注解时,不能继承其它注解或接口

步骤
  • 创建注解文件
  • 说明该注解能够使用的位置和保存的时期
  • 将注解贴到能够贴的位置
  • 为注解传递参数
/**
 * 用于标记某个映射方法是否需要登录访问
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredLogin {

}