什么是注解?为什么要使用注解?理解下annotation?
zhezhongyun 2024-12-03 06:31 32 浏览
推荐学习
一、什么是注解?
从 JDK5 开始,Java增加对元数据的支持,也就是注解。简单理解就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。
二、为什么要使用注解?
注解可以被其他程序(比如:编译器等)读取,开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。
三、注解的相关概述
3.1 注解的格式
注解就是以 @XXX 形式在代码中存在的,我们还可以为注解添加一些参数值,例如 @SuppressWarnings(value = "unchecked") 。
3.2 元注解
元注解就是负责注解其它注解的注解。
下图为Java定义的标准的 元注解类型,他们用来对其他的注解进行说明,可以在 Java API 的 java.lang.annotation 包中找到。
3.2.1 @Document
官方示例:
// since 1.5
@Documented
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Documented
官方描述:
- 如果注释@Documented出现在注释类型A的声明中,那么元素上的任何@A注释都被认为是元素公共契约的一部分。
- 更详细地说,当使用Documented对注释类型A进行注释时,类型A的注释的存在和值是A注释的元素的公共契约的一部分。相反,如果注释类型B没有被文档化注释,那么B注释的存在和值就不是B注释元素的公共契约的一部分。
- 具体地说,如果注释类型是用Documented注释的,那么默认情况下,像javadoc这样的工具将在其输出中显示该类型的注释,而没有Documented的注释类型的注释将不会显示。
间而言之:
如果使用了 @Documented ,就说明此类(或方法、字段等)的文档化注释就会被包含在JavaDoc中。
3.2.2 @Inherited
官方示例:
// since 1.5
@Documented
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Inherited
官方描述:
- 指示自动继承批注类型。
- 如果在注释类型声明上存在继承的元注释,并且用户在类声明上查询注释类型,而该类声明对此类型没有注释,则将自动在类的超类中查询注释类型。将重复此过程,直到找到此类型的注释,或到达类层次结构(对象)的顶部。
如果没有超类具有此类型的注释,则查询将指示所讨论的类没有此类注释。 - 请注意,如果注释类型用于注释类以外的任何内容,则此元注释类型无效。还要注意,这个元注释只会导致注释从超类继承;对实现接口的注释没有影响。
简而言之:
子类可以继承父类(超类)中的该注解。这个注解指定被他修饰的注解将具有继承性——如果某个类使用了@XXX,则其子类将自动被@XXX修饰
代码示例:
1 public class test2 {
2
3 public static void main(String[] args) {
4 Person person = new Person();
5 Student student = new Student();
6
7 Annotation[] parentAnnotation = person.getClass().getAnnotations();
8 Annotation[] studentAnnotation = student.getClass().getAnnotations();
9 for (Annotation annotation : parentAnnotation) {
10 System.out.println(annotation);
11 }
12 System.out.println("---------------------");
13 for (Annotation annotation : studentAnnotation) {
14 System.out.println(annotation);
15 }
16
17 // 输出结果
18 // @com.ruiyicloud.bbfbusiness.demo.annotation.MyAnnotation3()
19 // ---------------------
20 // @com.ruiyicloud.bbfbusiness.demo.annotation.MyAnnotation3()
21
22 }
23
24
25 }
26
27 @Target({ElementType.TYPE})
28 @Retention(RetentionPolicy.RUNTIME)
29 @Inherited
30 @interface MyAnnotation3{
31
32 }
33 @MyAnnotation3
34 class Person{
35 String name;
36 }
37
38 class Student extends Person{
39 int age;
40 }
注意:
如果 MyAnnotation3 注解 去掉 @Inherited,则student.getClass().getAnnotations() 将输入空。
3.2.3 @Native
官方代码:
// since 1.8
@Documented
@Target(FIELD)
@Retention(SOURCE)
public @interface Native
官方描述:
指示定义常量值的字段可以从本机代码引用。生成本机头文件的工具可以使用该注释作为提示,以确定是否需要头文件,如果需要,还应该包含哪些声明。
间而言之:
使用本地方法,我们可以用java与底层系统的交互,如果使用Java获取不到我们想要的内容,我们可以选择使用本地方法。
使用 @Native 注解修饰变量值的字段,则表示这个变量可以被本地代码引用。
代码示例:
附上Integer的部分源码
1 public final class Integer extends Number
2 implements Comparable<Integer>, Constable, ConstantDesc {
3 /**
4 * A constant holding the minimum value an {@code int} can
5 * have, -2<sup>31</sup>.
6 */
7 @Native public static final int MIN_VALUE = 0x80000000;
8
9
10
11 // 比较值的大小
12 public static int compareUnsigned(int x, int y) {
13 return compare(x + MIN_VALUE, y + MIN_VALUE);
14 }
3.2.4 @Repeatable
官方代码:
// since 1.8
@Documented
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Repeatable
官方描述:
注释类型java.lang.annotation注释.Repeatable用于指示它(meta-)注释其声明的注释类型是可重复的。@Repeatable的值表示可重复注释类型的包含注释类型。
间而言之:
使用@Repeatable这个声明的注解是可重复的。@Repeatable的值是另一个注解,其可以通过这个另一个注解的值来包含这个可重复的注解。
代码示例:
FooContainer 作用于范围只能在注解类型上,所以作用于接口上时会报错
1 import java.lang.annotation.ElementType;
2 import java.lang.annotation.Repeatable;
3 import java.lang.annotation.Target;
4
5 public class test03 {
6
7 }
8
9
10 @Target({ElementType.TYPE,ElementType.ANNOTATION_TYPE})
11 @Repeatable(FooContainer.class)
12 @interface Foo {}
13
14 @Target(ElementType.ANNOTATION_TYPE)
15 @interface FooContainer {
16 Foo[] value();
17 }
18
19 //正确的
20 @Foo @Foo
21 @interface FooContainer1 {
22 Foo[] value();
23 }
24
25 // 错误的
26 @Foo @Foo
27 interface aa {
28
29 }
注意事项:
- Foo的保留时间至少与FooContainer一样长,其中保留用@Retention 注释显式或隐式表示。特别:
- 如果Foo的保留为java.lang.annotation.RetentionPolicy.SOURCE,则FooContainer的保留为java.lang.annotation.RetentionPolicy.SOURCE。
- 如果Foo的保留值为java.lang.annotation.RetentionPolicy.CLASS,则FooContainer的保留值为java.lang.annotation.RetentionPolicy.CLASS或 java.lang.annotation.RetentionPolicy.SOURCE。
- 如果保留Foo是java.lang.annotation.RetentionPolicy.RUNTIME,则保留FooContainer是java.lang.annotation.RetentionPolicy.SOURCE, java.lang.annotation.RetentionPolicy.CLASS,或java.lang.annotation.RetentionPolicy.RUNTIME。
3.2.5 @Retention
官方示例:
// since 1.5
@Documented
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Retention
官方描述:
- 指示带批注类型的批注要保留多长时间。如果批注类型声明上不存在保留批注,则保留策略默认为保留策略.CLASS.
- 只有当元注释类型直接用于注释时,保留元注释才有效。如果元注释类型被用作另一个注释类型中的成员类型,则没有效果。
间而言之:
此注解主要作用为在什么级别保存该注解信息,用于描述注解的声明周期,需要主要的是 SOURCE < CLASS < RUNTIME 。
3.2.6 @Target
官方示例:
// since 1.5
@Documented
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Target
官方描述:
- 指示批注类型适用的上下文。JLS 9.6.4.1中指定了可应用注释类型的声明上下文和类型上下文,并在源代码中用java.lang.annotation注释.ElementType。
- 如果@Target元注释不存在于注释类型T上,那么类型T的注释可以作为除类型参数声明之外的任何声明的修饰符来编写。
- 如果存在@Target元注释,编译器将根据JLS 9.7.4强制执行由ElementType enum常量指示的使用限制。
简而言之:
@Target注解主要用于描述注解的使用范围(例如,添加某些属性的时候注解可以使用在类上,添加某些属性的时候注解可以使用在方法上等)
3.3 注解的使用范围?
ElementType枚举常量
3.4 常用的几个注解
@Override :
限定父类重写方法,当子类重写父类方法时,子类可以加上这个注解,可以确保子类确实重写了父类的方法,避免出现低级错误。
@FunctionalInterface:
函数式接口,注解保证这个接口只有一个抽象方法,注意这个只能修饰接口。(函数式接口是指 接口中只有一个抽象方法(可以包含多个默认方法或多个static方法),接口体内只能声明常量字段和抽象方法,并且被隐式声明为public,static,final。接口里面不能有私有的方法或变量。)
@Deprecated:
标示已过时,这个注解用于表示某个程序元素类,方法等已过时,当其他程序使用已过时的类,方法时编译器会给出警告。
@SuppressWarning:
抑制编译器警告,被该注解修饰的元素以及该元素的所有子元素取消显示编译器警告。
四、自定义注解实战
本例创建一个简单的注解,并在方法上、类上进行使用
@MyAnnotation
public class Main {
@MyAnnotation
public static void main(String[] args) {
}
}
// Target 标识注解可以在什么地方使用
@Target({ElementType.METHOD,ElementType.TYPE})
// 标识此注解在什么地方还有效
@Retention(RetentionPolicy.RUNTIME)
// 标识是否将我们的注解生成在JavaDoc中
@Documented
// 子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}
五、总结
总的来说,注解还是比较简单的。
作者: 学海无涯519
原文链接:https://www.cnblogs.com/wgx519/p/14373086.html
相关推荐
- JPA实体类注解,看这篇就全会了
-
基本注解@Entity标注于实体类声明语句之前,指出该Java类为实体类,将映射到指定的数据库表。name(可选):实体名称。缺省为实体类的非限定名称。该名称用于引用查询中的实体。不与@Tab...
- Dify教程02 - Dify+Deepseek零代码赋能,普通人也能开发AI应用
-
开始今天的教程之前,先解决昨天遇到的一个问题,docker安装Dify的时候有个报错,进入Dify面板的时候会出现“InternalServerError”的提示,log日志报错:S3_USE_A...
- 用离散标记重塑人体姿态:VQ-VAE实现关键点组合关系编码
-
在人体姿态估计领域,传统方法通常将关键点作为基本处理单元,这些关键点在人体骨架结构上代表关节位置(如肘部、膝盖和头部)的空间坐标。现有模型对这些关键点的预测主要采用两种范式:直接通过坐标回归或间接通过...
- B 客户端流RPC (clientstream Client Stream)
-
客户端编写一系列消息并将其发送到服务器,同样使用提供的流。一旦客户端写完消息,它就等待服务器读取消息并返回响应gRPC再次保证了单个RPC调用中的消息排序在客户端流RPC模式中,客户端会发送多个请...
- 我的模型我做主02——训练自己的大模型:简易入门指南
-
模型训练往往需要较高的配置,为了满足友友们的好奇心,这里我们不要内存,不要gpu,用最简单的方式,让大家感受一下什么是模型训练。基于你的硬件配置,我们可以设计一个完全在CPU上运行的简易模型训练方案。...
- 开源项目MessageNest打造个性化消息推送平台多种通知方式
-
今天介绍一个开源项目,MessageNest-可以打造个性化消息推送平台,整合邮件、钉钉、企业微信等多种通知方式。定制你的消息,让通知方式更灵活多样。开源地址:https://github.c...
- 使用投机规则API加快页面加载速度
-
当今的网络用户要求快速导航,从一个页面移动到另一个页面时应尽量减少延迟。投机规则应用程序接口(SpeculationRulesAPI)的出现改变了网络应用程序接口(WebAPI)领域的游戏规则。...
- JSONP安全攻防技术
-
关于JSONPJSONP全称是JSONwithPadding,是基于JSON格式的为解决跨域请求资源而产生的解决方案。它的基本原理是利用HTML的元素标签,远程调用JSON文件来实现数据传递。如果...
- 大数据Doris(六):编译 Doris遇到的问题
-
编译Doris遇到的问题一、js_generator.cc:(.text+0xfc3c):undefinedreferenceto`well_known_types_js’查找Doris...
- 网页内嵌PDF获取的办法
-
最近女王大人为了通过某认证考试,交了2000RMB,官方居然没有给线下教材资料,直接给的是在线教材,教材是PDF的但是是内嵌在网页内,可惜却没有给具体的PDF地址,无法下载,看到女王大人一点点的截图保...
- 印度女孩被邻居家客人性骚扰,父亲上门警告,反被围殴致死
-
微信的规则进行了调整希望大家看完故事多点“在看”,喜欢的话也点个分享和赞这样事儿君的推送才能继续出现在你的订阅列表里才能继续跟大家分享每个开怀大笑或拍案惊奇的好故事啦~话说只要稍微关注新闻的人,应该...
- 下周重要财经数据日程一览 (1229-0103)
-
下周焦点全球制造业PMI美国消费者信心指数美国首申失业救济人数值得注意的是,下周一希腊还将举行第三轮总统选举需要谷歌日历同步及部分智能手机(安卓,iPhone)同步日历功能的朋友请点击此链接,数据公布...
- PyTorch 深度学习实战(38):注意力机制全面解析
-
在上一篇文章中,我们探讨了分布式训练实战。本文将深入解析注意力机制的完整发展历程,从最初的Seq2Seq模型到革命性的Transformer架构。我们将使用PyTorch实现2个关键阶段的注意力机制变...
- 聊聊Spring AI的EmbeddingModel
-
序本文主要研究一下SpringAI的EmbeddingModelEmbeddingModelspring-ai-core/src/main/java/org/springframework/ai/e...
- 前端分享-少年了解过iframe么
-
iframe就像是HTML的「内嵌画布」,允许在页面中加载独立网页,如同在画布上叠加另一幅动态画卷。核心特性包括:独立上下文:每个iframe都拥有独立的DOM/CSS/JS环境(类似浏...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- HTML 参考手册 (28)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML中如何键入空格 (27)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)