一文带你深入理解【Java基础】· 注解

news2025/7/15 8:38:57

写在前面


        Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误不足之处,请多多指正!谢谢大家!!!

        如果小哥哥小姐姐们对我的文章感兴趣,请不要吝啬你们的小手,多多点赞加关注呀!❤❤❤ 爱你们!!!


目录

写在前面

1. 注解概述

1.1 注解 (Annotation) 概述

1.2 常见的Annotation示例

 2. 自定义 Annotation

2.1 自定义注解说明

2.2 JDK 中的元注解

2.3 利用反射获取注解信息

2.4 JDK8中注解的新特性

3. 注解代码演示

3.1 注解的使用

结语


【往期回顾】

一文带你深入理解【Java基础】· 枚举类

一文带你深入理解【Java基础】· 常用类(上)字符串相关类

一文带你深入理解【Java基础】· 多线程(上)

一文带你深入理解【Java基础】· 异常处理

一文带你深入理解【Java基础】· 面向对象编程(上)

一文带你深入理解【Java基础】· 数组


1. 注解概述


1.1 注解 (Annotation) 概述

  • JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是Annotation(注解)
  • Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
  • Annotation 可以像修饰符一样被使用, 可用于修饰包,, 构造器, , 成员变量, 参数, 局部变量的声明, 这些信息被保存在 Annotation的 “name=value” 对中。
  • JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。
  • 未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架 = 注解 + 反射 + 设计模式。

1.2 常见的Annotation示例

        使用 Annotation 时要在其前面增加 @ 符号, 把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元素

示例一:生成文档相关的注解

  • @author 标明开发该类模块的作者,多个作者之间使用,分割
  • @version 标明该类模块的版本
  • @see 参考转向,也就是相关主题
  • @since 从哪个版本开始增加的
  • @param 对方法中某参数的说明,如果没有参数就不能写
  • @return 对方法返回值的说明,如果方法的返回值类型是void就不能写
  • @exception 对方法可能抛出的异常进行说明 ,如果方法没有用throws显式抛出的异常就不能写。其中:
    • @param @return @exception 这三个标记都是只用于方法的。
    • @param的格式要求:@param 形参名 形参类型 形参说明
    • @return 的格式要求:@return 返回值类型 返回值说明
    • @exception的格式要求:@exception 异常类型 异常说明
    • @param@exception可以并列多个
package com.annotation.javadoc;
/**
* @author linxiaobai
* @version 1.0
* @see Math.java
*/
public class JavadocTest {
    /**
    * 程序的主方法,程序的入口
    * @param args String[] 命令行参数
    */
    public static void main(String[] args) {

    }
    /**
    * 求圆面积的方法
    * @param radius double 半径值
    * @return double 圆的面积
    */
    public static double getArea(double radius) {
        return Math.PI * radius * radius;
    }
}

示例二:在编译时进行格式检查 (JDK 内置的三个基本注解 )
  • @Override: 限定重写父类方法, 该注解只能用于方法
  • @Deprecated: 用于表示所修饰的元素(, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
  • @SuppressWarnings: 抑制编译器警告
package com.annotation.javadoc;
public class AnnotationTest {
    public static void main(String[] args) {
        @SuppressWarnings("unused")
        int a = 10;
    }
    @Deprecated
    public void print() {
        System.out.println("过时的方法");
    }
    @Override
    public String toString() {
        return "重写的toString方法()";
    }
}

示例三:跟踪代码依赖性,实现替代配置文件功能
  • Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署。
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
    } 
}
<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>
  • spring框架中关于“事务”的管理
@Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_COMMITTED,readOnly=false,timeout=3)
public void buyBook(String username, String isbn) {
    //1.查询书的单价
    int price = bookShopDao.findBookPriceByIsbn(isbn);
    //2. 更新库存
    bookShopDao.updateBookStock(isbn);
    //3. 更新用户的余额
    bookShopDao.updateUserAccount(username, price);
}
<!-- 配置事务属性 -->
<tx:advice transaction-manager="dataSourceTransactionManager" id="txAdvice">
    <tx:attributes>
    <!-- 配置每个方法使用的事务属性 -->
    <tx:method name="buyBook" propagation="REQUIRES_NEW"
        isolation="READ_COMMITTED" read-only="false" timeout="3" />
    </tx:attributes>
</tx:advice>


 2. 自定义 Annotation


2.1 自定义注解说明

  • 定义新的 Annotation 类型使用 @interface 关键字
  • 自定义注解自动继承了java.lang.annotation.Annotation接口
  • Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明。其方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组
  • 可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字
  • 如果只有一个参数成员,建议使用参数名为value
  • 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是“参数名 = 参数值” ,如果只有一个参数成员,且名称为value,可以省略“value=
  • 没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation
  • 注意:自定义注解必须配上注解的信息处理流程才有意义。

2.2 JDK 中的元注解

  • JDK 的元 Annotation 用于修饰其他 Annotation 定义
  • JDK5.0提供了4个标准的meta-annotation类型,分别是:
    • Retention
    • Target
    • Documented
    • Inherited

  • @Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 的生命周期, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用@Rentention 时必须为该 value 成员变量指定值:
    • RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释
    • RetentionPolicy.CLASS:class文件中有效(即class保留) , 当运行 Java 程序时, JVM不会保留注解。 这是默认值
    • RetentionPolicy.RUNTIME:在运行时有效(即运行时保留),当运行 Java 程序时, JVM 保留注释。程序可以通过反射获取该注释。

 

  • @Target: 用于修饰 Annotation 定义, 用于指定被修饰的 Annotation 能用于修饰哪些程序元素。 @Target 也包含一个名为 value 的成员变量。

  • @Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被javadoc 工具提取成文档。默认情况下,javadoc是不包括注解的。
    • 定义为Documented的注解必须设置Retention值为RUNTIME
  • @Inherited: 被它修饰的 Annotation 将具有继承性。如果某个类使用了被@Inherited 修饰的 Annotation, 则其子类将自动具有该注解。
    • 比如:如果把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解
    • 实际应用中,使用较少

2.3 利用反射获取注解信息

  • JDK 5.0 java.lang.reflect 包下新增了 AnnotatedElement 接口, 该接口表程序中可以接受注解的程序元素
  • 当一个 Annotation 类型被定义为运行时 Annotation , 该注解才是运行时可见, class 文件被载入时保存在 class 文件中的 Annotation 才会被虚拟机读取
  • 程序可以调用 AnnotatedElement对象的如下方法来访问 Annotation 信息


2.4 JDK8中注解的新特性

        Java 8对注解处理提供了两点改进: 可重复的注解 可用于类型的注解 。此外,反射也得到了加强,在Java8 中能够得到方法参数的名称。这会简化标注在方法参数上的注解。
可重复注解示例:

 

类型注解:
  • JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个: TYPE_PARAMETER,TYPE_USE
  • Java 8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。
  • ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
  • ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。
public class TestTypeDefine<@TypeDefine() U> {
    private U u;
    public <@TypeDefine() T> void test(T t) {
    }
}
@Target({ElementType.TYPE_PARAMETER})
@interface TypeDefine {
}
@MyAnnotation
public class AnnotationTest<U> {
    @MyAnnotation
    private String name;
    public static void main(String[] args) {
        AnnotationTest<@MyAnnotation String> t = null;
        int a = (@MyAnnotation int) 2L;
        @MyAnnotation
        int b = 10;
    }
    public static <@MyAnnotation T> void method(T t) {
    }
    public static void test(@MyAnnotation String arg) throws @MyAnnotation Exception {
    }
}
@Target(ElementType.TYPE_USE)
@interface MyAnnotation {
}

3. 注解代码演示


3.1 注解的使用

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Date;

/**
 * 注解的使用
 *
 * 1. 理解Annotation:
 * ① jdk 5.0 新增的功能
 *
 * ② Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。通过使用 Annotation,
 * 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。
 *
 * ③在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android
 * 中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗
 * 代码和XML配置等。
 *
 * 2. Annocation的使用示例
 * 示例一:生成文档相关的注解
 * 示例二:在编译时进行格式检查(JDK内置的三个基本注解)
 @Override: 限定重写父类方法, 该注解只能用于方法
 @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
 @SuppressWarnings: 抑制编译器警告

  * 示例三:跟踪代码依赖性,实现替代配置文件功能
  *
  * 3. 如何自定义注解:参照@SuppressWarnings定义
  * ① 注解声明为:@interface
  * ② 内部定义成员,通常使用value表示
  * ③ 可以指定成员的默认值,使用default定义
  * ④ 如果自定义注解没有成员,表明是一个标识作用。

 如果注解有成员,在使用注解时,需要指明成员的值。
 自定义注解必须配上注解的信息处理流程(使用反射)才有意义。
 自定义注解通过都会指明两个元注解:Retention、Target

 4. jdk 提供的4种元注解
 元注解:对现有的注解进行解释说明的注解
 Retention:指定所修饰的 Annotation 的生命周期:SOURCE\CLASS(默认行为)\RUNTIME
 只有声明为RUNTIME生命周期的注解,才能通过反射获取。
 Target:用于指定被修饰的 Annotation 能用于修饰哪些程序元素
  *******出现的频率较低*******
 Documented:表示所修饰的注解在被javadoc解析时,保留下来。
 Inherited:被它修饰的 Annotation 将具有继承性。

 5.通过反射获取注解信息 ---到反射内容时系统讲解

 6. jdk 8 中注解的新特性:可重复注解、类型注解

 6.1 可重复注解:
 ① 在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class
 ② MyAnnotation的Target和Retention等元注解与MyAnnotations相同。

 6.2 类型注解:
 ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
 ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。
 */
public class AnnotationTest {
    public static void main(String[] args) {
        Person p = new Student();
        p.walk();

        Date date = new Date(2020, 10, 11);
        System.out.println(date);

        @SuppressWarnings("unused")
        int num = 10;
        // System.out.println(num);

        @SuppressWarnings({"unused", "rawtypes"})
        ArrayList list = new ArrayList();
}

    @Test
    public void testGetAnnotation() {
        Class clazz = Student.class;
        Annotation[] annotations = clazz.getAnnotations();
        for (int i = 0; i < annotations.length; i++) {
            System.out.println(annotations[i]);
        }
    }
}

// jdk 8之前的写法:
// @MyAnnotations({@MyAnnotation(value="hi"),@MyAnnotation(value="hi")})
@MyAnnotation(value = "hi")
@MyAnnotation(value = "abc")
class Person {
    private String name;
    private int age;

    public Person() {
    }

    @MyAnnotation
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @MyAnnotation
    public void walk() {
        System.out.println("人走路");
    }

    public void eat() {
        System.out.println("人吃饭");
    }
}

interface Info {
    void show();
}

class Student extends Person implements Info {

    @Override
    public void walk() {
        System.out.println("学生走路");
    }

    public void show() {

    }
}

class Generic<@MyAnnotation T> {
    public void show() throws @MyAnnotation RuntimeException {
        ArrayList<@MyAnnotation String> list = new ArrayList<>();
        int num = (@MyAnnotation int) 10L;
    }
}

结语


本人会持续更新文章的哦!希望大家一键三连,你们的鼓励就是作者不断更新的动力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38160.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多线程编程【条件变量】

条件变量&#x1f4d6;1. 为什么需要条件变量&#xff1f;&#x1f4d6;2. 条件变量概念&#x1f4d6;3. 发信号时总是持有锁&#x1f4d6;4. 生产者消费者问题&#x1f4d6;5. 基于阻塞队列的生产者消费者模型&#x1f4d6;1. 为什么需要条件变量&#xff1f; 在很多情况下&a…

Android开发音效增强中铃声播放Ringtone及声音池调度SoundPool的讲解及实战(超详细 附源码)

需要源码请点赞关注收藏后评论区留下QQ~~~ 一、铃声播放 虽然媒体播放器MediaPlayer既可用来播放视频&#xff0c;也可以用来播放音频&#xff0c;但是在具体的使用场合&#xff0c;MediaPlayer存在某些播音方面的不足之处 包括以下几点 1&#xff1a;初始化比较消耗资源 尤其…

软件开发工程师笔试记录--关键路径,浮点数计算,地址变换,中断向量,I/O接口,海明码

时间&#xff1a;2022年11月26日 10&#xff1a;00 -11&#xff1a;00 &#xff08;可提前登录15分钟&#xff09; 公司&#xff1a;XX&#xff08;rongyu&#xff09; 岗位&#xff1a;软件开发工程师&#xff08;我的简历语言是Java&#xff09; 题型&#xff1a;选择题&…

一次应用多次fgc原因的排查及解决

应用多次fgc性能排查&#xff08;一次抢购引起的性能问题&#xff09; 大家好我是魔性的茶叶&#xff0c;今天分享一个项目jvm多次fgc的整个排查流程 上班后不久运维突然通知我们组&#xff0c;有一个应用在短时间内多次fgc&#xff0c;即将处于挂掉的状态。 首先我登录skyw…

客户听不进去,很强势,太难沟通了,怎么办?

案例 最近接手一项目,项目范围蔓延,成本超支,进度延期,问项目经理怎么回事? 项目经理C无奈诉苦到:用户A大领导,是业主B的领导,咱们业主B不敢反驳他,让我直接与用户A对接,说A提的需求,默认答应,我有什么办法啊,只能接了。 分析 经过复盘,导致项目蔓延的主要原因…

【参赛经历总结】第五届“传智杯”全国大学生计算机大赛(初赛B组)

成绩 比赛链接 比赛过程 被虐4h 比赛体验不是很好我开始五分后才在qq上看到题第一题签到题第二题调了1h吧&#xff0c;算法题做的不多&#xff0c;题目没读全&#xff0c;wa了几发&#xff0c;有几发是网络问题&#xff0c;交了显示失败&#xff0c;但还是判wa了第三题知道…

mulesoft What‘s the typeOf(payload) of Database Select

Whats the typeOf payload of Database SelectQuestionOptionExplanationMule ApplicationDebugQuestion Refer to the exhibit. The Database Select operation returns five rows from a database. What is logged by the Logger component? Option A “Array” B “Objec…

第五届传智杯-初赛【B组-题解】

A题 题目背景 在宇宙射线的轰击下&#xff0c;莲子电脑里的一些她自己预定义的函数被损坏了。 对于一名理科生来说&#xff0c;各种软件在学习和研究中是非常重要的。为了尽快恢复她电脑上的软件的正常使用&#xff0c;她需要尽快地重新编写这么一些函数。 你只需输出fun(a,…

数据库错误知识集3(摘)

&#xff08;摘&#xff09; 逻辑独立性是外模式不变&#xff0c;模式改变时&#xff0c;如增加新的关系&#xff0c;新的属性&#xff0c;改变属性的数据类型&#xff0c;由数据库管理员对各个外模式/模式的映像做相应改变&#xff0c;可以使得外模式不变&#xff0c;因为应用…

sdfsdfasfsdfdsfasfdfasfasadsfasdfasf

白包api 图片编辑功能&#xff1a; 1、你变体下 SnapEditMenuManager 的 这个方法 public void initEditMainMenu(final EditUITabMenu editUITabMenu) 换成你需要的配置&#xff0c;需要哪个功能 就拿哪一坨&#xff0c;别拿多了 //相框 MenuBean menuBean new MenuBean…

线程的学习

v# 1. 线程基本概念 1.1进程 进程是指运行中的程序&#xff0c;比如启动了QQ&#xff0c;就相当于启动了一个进程&#xff0c;操作系统会为该进程分配空间&#xff1b;当我们使用迅雷&#xff0c;就相当于又启动了一个进程&#xff0c;操作系统将为迅雷分配新的内存空间&…

坦克大战①

1. java绘图技术 JFrame&#xff1a;画板 Jpanel&#xff1a;画板 Graphics&#xff1a;画笔 初始化画板&#xff0c;定义画框的大小&#xff0c;设置可视化&#xff1b; 1.1 画坦克 初始化我方坦克、敌方坦克 绘图&#xff1a;(1)更改背景颜色&#xff1b;(2)绘制敌方坦克…

【Docker】常用命令

背景 当下&#xff0c;docker技术已成为开发者常用的技术栈。不管是开发过程中需要应对的各种复杂多变的开发环境的搭建&#xff0c;还是生产部署环节需要的自动化运维&#xff0c;都离不开docker&#xff0c;本文简单介绍相关命令的含义&#xff0c;用作平时查询使用。 1. doc…

【计算机毕业设计】38.网上轰趴预订系统

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘要 在网上轰趴发展的整个过程中&#xff0c;网上轰趴预定担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类网上轰趴程序也在不断改进。本课题所设计的网上轰趴预定系统&#xff0c;使用SSM框架…

一文看懂Transformer(详解)

文章目录Transformer前言网络结构图&#xff1a;EncoderInput EmbeddingPositional Encoderself-attentionPadding maskAdd & NormFeed ForwardDecoderinputmasked Multi-Head Attentiontest时的Decoder预测Transformer 前言 Transformer最初是用于nlp领域的翻译任务。 …

大屏图表,ECharts 从“熟练”到入门

&#x1f4d6;阅读本文&#xff0c;你将 了解 配置驱动 的思想理解 Echarts 基本概念了解 graphic 和 动画基本玩法。了解 Echarts 基底组件的封装的思路 一、不是标题党&#xff01;Echarts&#xff0c;简历上人均 “熟练”&#xff1f; 公司最近在招外包&#xff0c;而因为…

基于ASP学生资助管理系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做ASP程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问题…

用Python蹭别人家图片接口,做一个【免费图床】吧

打开本文&#xff0c;相信你确实需要一个免费且稳定的图床&#xff0c;这篇博客就让你实现。 文章目录⛳️ 谁家的图床⛳️ 实战编码⛳️ 第一轮编码⛳️ 第二轮编码⛳️ 第三轮编码⛳️ 第四轮编码⛳️ 谁家的图床 这次咱们用新浪微博来实现【免费图床应用】&#xff0c;通过…

栈浅谈(上)

目录 栈的定义 栈的实现 初始化 判断栈是否为空 入栈操作 获取栈顶元素 出栈操作 遍历栈 销毁栈 完整代码演示 栈—STL 基本操作 例题 参考代码 栈的定义 说到栈&#xff0c;一些不会计算机语言的“小白”&#xff08;我就是&#xff09;就会想到栈道之类的词语…

基于JavaWeb的婚恋交友网站设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…