Java注解
介绍
注解(Annotation)也被称为元数据,用于修饰解释 包、类、方法、属性、构造器、局部变量和方法参数等数据信息。
和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息,用来对这些元素进行说明。
使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素。
生成api文档相关注解:
/*****类文档注释中使用的注解*****/ @author:标明开发该类模块的作者,多个作者之间使用,分隔 @version:标明该类模块的版本 @see:参考转向,也就是相关主题 @since:从哪个版本开始增加的 /*****方法文档注释使用的注解*****/ @param:对方法中某参数的说明,如果没有参数就不能写。格式:@param 形参名 形参类型 形参说明 @return:对方法返回值的说明,如果方法的返回值类型是void就不能写。格式:@return 返回值类型 返回值说明 @exception:对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写其中。格式:@exception 异常类型 异常说明 // @param和@exception可以并列多个
作用分类:
①编写文档:通过代码里标识的注解生成文档(使用jdk工具javadoc生成doc文档)
②代码分析:通过代码里标识的注解对代码进行分析(使用反射)
③编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查(基本注解如:@Override)
三个基本Annotation:
@Override:限定某个方法,是重写父类方法,该注解只能用于方法
@Deprecated:用于表示某个程序元素(类,方法等)已过时
@SuppressWarnings:抑制编译器警告
自定义注解
注解格式
@元注解 public @interface 注解名称 { 属性列表; }
@interface表示是注解类,不是接口interface;是JDK1.5之后加入的。
注解本质
自定义一个注解:
public @interface MyAnnotation { }
通过javap
反编译我们可以看到,其实注解本质上就是一个接口,该接口默认继承Annotation
接口
属性定义
注解本身就是一个接口,而接口中我们可以定义各种属性(抽象方法)。
属性的返回值类型有以下几种:
8种基本数据类型
String
枚举
注解
Class(类)
以上类型的数组
举个🌰:
public @interface MyAnnotation { // "注解属性定义" int number(); String name(); CityEnum cityEnum(); CityAnnotation cityAnnotation(); String[] cityArray(); } enum CityEnum { HANG_ZHOU("杭州"), SHANG_HAI("上海"), BEI_JING("北京"), HA_ER_BIN("哈尔滨"); String name; CityEnum(String name) { this.name = name; } } @interface CityAnnotation { }
自定义注解使用🌰
/* * 定义了属性,使用时需要给属性赋值 * 1.如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值,没有初始化值则必须使用时赋值 * 2.如果只有一个属性需要赋值,并且属性的名称时 value,则'value='可以省略,直接定义值即可 * 3.数组赋值时,值使用 {} 包裹。如果数组中只有一个值,则可以省略 {} * */ @MyAnnotation(number = 1, name = "hguo", cityEnum = CityEnum.HANG_ZHOU, cityAnnotation = @CityAnnotation, cityArray = {"666", "978"}) public class TestAnnotation { }
如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值,没有初始化值则必须使用时赋值
@MyAnnotation public class TestAnnotation { } public @interface MyAnnotation { // default给属性初始化赋值 int number() default 1; }
如果只有一个属性需要赋值,并且属性的名称时 value,则'value='可以省略,直接定义值即可
@MyAnnotation("hangzhou") public class TestAnnotation { } public @interface MyAnnotation { // 属性名称为value String value(); }
数组赋值时,值使用 '{ }' 包裹。如果数组中只有一个值,则可以省略 '{ }'
@MyAnnotation(name = "hangzhou") // 只有一个值可以省略{} public class TestAnnotation { } public @interface MyAnnotation { // 数组类型属性 String[] name(); }
元注解
用于描述注解的注解。
@Target
描述注解能够作用的位置范围,内部定义了ElementType
类型数组属性。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }
ElementType常用取值:
TYPE:用于描述类、接口(包括注解类型)或enum
METHOD:用于描述方法
FIELD:用于描述成员变量(域)
CONSTRUCTOR:用于描述构造器
LOCAL_VARIABLE:用于描述局部变量
PACKAGE:用于描述包
PARAMETER:用于描述参数
@Retention
描述注解被保留的阶段。内部定义了RetentionPolicy
类型属性。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }
@Retention(RetentionPolicy.SOURCE)
RetentionPolicy中包括以下三种:
RetentionPolicy.RUNTIME:当前被被描述的注解,会保留class字节码文件中,并被JVM读取到。也是常用的类型。只有声明为RUNTIME生命周期的注解,才能通过反射获取。
RetentionPolicy.CLASS:当前被被描述的注解,会保留class字节码文件中,但是不会被JVM读取到。默认值类型。
RetentionPolicy.SOURCE:当前被被描述的注解,不会保留class字节码文件中,更不会被JVM读取到。
@Documented
被该注解修饰的Annotation将被javadoc工具提取成文档。默认情况下,javadoc是不包括注解的。
定义为@Documented的注解必须设置Retention值为RUNTIME。
@Inherited
描述注解是否被子类继承,具有继承性。(使用较少)例如:父类使用了自定义注解,且自定义注解中的元注解声明了@Inherited
,子类也会继承父类使用的自定义注解。
🌰:
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MyAnnotation { String[] name(); }
本文来自博客园,作者:Lz_蚂蚱,转载请注明原文链接:https://www.cnblogs.com/leizia/p/16443258.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步