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

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

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

推荐学习

  • 牛掰!“基础-中级-高级”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{

}

五、总结

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

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 &quot;小贱贱&quot;韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...