百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

什么是注解?为什么要使用注解?理解下annotation?

myzbx 2024-12-03 16:40 43 浏览

推荐学习

  • 牛掰!“基础-中级-高级”Java程序员面试集结,看完献出我的膝盖

  • 真真香!耗时大半个月收整全套「Java架构进阶pdf」没白费

一、什么是注解?

  从 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{

}

五、总结

  总的来说,注解还是比较简单的。

相关推荐

一键生成高颜值图表!让你的文字瞬间有画面感,职场人必备!

哈喽,打工人们!忙碌的周中,大熊又来给你们带来一个超实用的效率神器啦!这次的宝藏网站绝对是那种用过就离不开的"真香"型产品!假设你明天就要做重要汇报,可面对一大堆密密麻麻的文字材料,你...

批量将 Word 转换为 PDF/Excel/Txt/图片等多种格式

Word文档是我们工作中经常会打交道的一种文档格式,我们也经常会有需要对Word文档进行格式转换的需求,比如将Word格式转换为PDF、将Word文档转换为Excel、将Word...

绝了!一键用AI生成高颜值动态PPT(附详细步骤+Prompt)

大家好,我是一名酷爱研究AI的产品经理,最近我有个新发现:那些花了你3天做出来的PPT,现在用AI可以1小时搞定!而且颜值还高!为什么AI做PPT比传统方式效率高10倍?我用一张图就能告诉你:AI生成...

ztext - 简单几行代码创建酷炫3D特效文字的开源JS库

把网页上的文字变成酷炫的3D风格,还能制作旋转动效,有了ztext.js,只需要几行代码。ztext能做什么ztext.js是一个能把常规的平面文字变成3D样式的前端开源代码库,让开发者...

文字内插入小图片,也太可爱了吧(文字中怎么插图片)

图文排版H5手机版秀米有小伙伴留言问添加图片的时候可不可以把图片添加到文字之间比如下面这句话中的小贴纸图片后面可以接着输入文字其实吧这就是咱们的『文字内插入小图片』功能嘛可以用来在文字内加个表情包又...

Linux环境下C++代码性能分析方法(linux怎么写c++代码)

技术背景在开发C++应用程序时,找出代码中运行缓慢的部分是进行性能优化的关键。在Linux系统上,有多种工具和方法可用于对C++代码进行性能分析,每种方法都有其特点和适用场景。实现步骤手动中断调试法在...

SVG互动图文,让你的文章更有趣!教你4种简单易学的黑科技玩法!

如果你是一个公众号创作者,那么你一定想知道如何让你的文章更加吸引人,更加有趣,更加有创意。你可能已经尝试过各种图文排版技巧,但是你是否知道,有一种黑科技可以让你的文章变得更加酷炫,更加互动,更加爆款?...

Videoscribe怎么实现实心中文汉字的手绘制作

很多朋友在制作手绘视频的时候,不知道怎么输入实心的中文汉字,之前我们已经给大家分享了怎么输入汉字的方法,但是有一点遗憾的是输出的汉字是空心的手绘展示,在视觉上并不是非常的美观。经过大家不断的探索,终于...

一款用于将文本转化成图表的现代化脚本语言

大家好,又见面了,我是GitHub精选君!今天要给大家推荐一个GitHub开源项目terrastruct/d2,该项目在GitHub有超过10.3kStar,用一句话介绍该项目就是:...

探秘 Web 水印技术(制作水印网站)

作者:fransli,腾讯PCG前端开发工程师Web水印技术在信息安全和版权保护等领域有着广泛的应用,对防止信息泄露或知识产品被侵犯有重要意义。水印根据可见性可分为可见水印和不可见水印(盲水印)...

不忍心卸载的五款神仙工具(不忍心卸载的五款神仙工具是什么)

001.效率工具uTools-装机必备的生产力工具集uTools是一款非常强大的可以装下几乎所有效率工具的电脑生产力工具集,目前拥有Windows、Mac和Linux三个版本。软件界面...

「SVG」飞花令!这份最高检工作报告“超有料”

原标题:【SVG】飞花令!这份最高检工作报告“超有料”栏目主编:秦红文字编辑:沈佳灵来源:作者:最高人民检察院...

svg|2025政府工作报告,有没有你关心的数据?

··<setattributeName="visibility"begin="click+0s"dur="1ms"fill="freeze"restart="never"to="hi...

videoscribe只能输入英文,如何输入中文文本?

videoscribe只能输入英文,如何输入中文文本?打开VideoScribe软件,打开要添加中文字体的位置。打开Photoshop并在文件中创建一个新的透明背景图层。注意:必须是透明背景层。...

五个流行的SVG在线编辑器(svg编辑工具)

随着响应网络的发展,越来越多的高质量的SVG在线编辑器被公众所熟知。SVG矢量图形也越来越受欢迎,以便在任何设备上呈现图像,甚至一些易于使用的SVG在线编辑器,可以替代PS,本文总结了五种流行的SVG...