自定义注解和@Target、@Retention注解的使用

news2024/10/5 14:24:46

说明:注解可以理解为另一种形式的配置,可用于在类上、方法上等,标志是“@”,如重写方法上的“@Override”就是一种注解。这里我通过一个实例,来介绍自定义注解和java元注解(@Target、@Retention)的使用

自定义注解

在idea中鼠标右键创建一个类,选择“Annotation”可创建一个注解;我这里创建了一个MyAnnotate注解,设置了一个int类型的times属性,默认值是1
在这里插入图片描述

/**
 * 自定义注解
 *
 * @author 10765
 */
public @interface MyAnnotate {
    // 定义属性times,表示次数,默认值为1
    int times() default 1;
}

@Target注解

java元注解的一种,表示当前注解可使用的类型,查看java源码,可以看到有以下待选:

public enum ElementType {
    // 类、接口(包括注释类型)或枚举声明
    TYPE,
    
    // 字段声明(包括枚举常量)
    FIELD,

    // 方法声明
    METHOD,

    // 形式参数声明
    PARAMETER,

    // 构造函数声明
    CONSTRUCTOR,

    // 局部变量声明
    LOCAL_VARIABLE,

    // 注解类型声明
    ANNOTATION_TYPE,

    // 包声明
    PACKAGE,

    /**
     * 类型参数声明
     *
     * 自JDK1.8出现
     */
    TYPE_PARAMETER,

    /**
     * 使用类型
     *
     * 自JDK1.8出现
     */
    TYPE_USE,

    /**
     * 模块声明
     *
     * 自JDK9出现
     */
    MODULE
}

如上面我自定义的注解,我想只能用于方法上,就可以设置为“@Target(ElementType.METHOD)”

/**
 * 自定义注解
 * @author 10765
 */
// 指定该注解只能用于方法上
@Target(ElementType.METHOD)
public @interface MyAnnotate {
    // 定义属性times,表示次数,默认值为1
    int times() default 1;
}

@Retention注解

表示当前注解存活,或者说可使用的阶段,默认是存活在字节码阶段。查看java源码,有以下待选:

public enum RetentionPolicy {
    /**
     * 编译器将丢弃注释
     */
    SOURCE,

    /**
     * 注解将由编译器记录在类文件中,但不需要在运行时由 VM 保留。这是默认行为。
     */
    CLASS,

    /**
     * 注解将由编译器记录在类文件中,并由 VM 在运行时保留,以便可以反射方式读取它们。
     */
    RUNTIME
}

我先不作设置,用实例执行以下我的注解,看下效果

实例

先创建一个学生系统的操作Demo类,并在方法上添加注解,以后使用,想达到的效果是仅执行带有注解的方法,并且根据注解的times值,执行对应的次数

/**
 * 学生操作
 */
public class StudentOperate {
    public void save() {
        System.out.println("save running......");
    }

    public void delete() {
        System.out.println("delete running......");
    }

    @MyAnnotate
    public void update() {
        System.out.println("update running......");
    }

    @MyAnnotate(times = 3)
    public void get() {
        System.out.println("get running......");
    }
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {
        // 获取StudentOperate类的Class对象
        Class stuOperateClass = Class.forName("com.essay02.StudentOperate");

        // 获取StudentOperate类的所有方法对象
        Method[] methodObjs = stuOperateClass.getDeclaredMethods();
        
        // 生成一个Class对象的实例化对象
        Object stuOpObj = stuOperateClass.newInstance();

        // 遍历所有方法对象
        for (Method methodObj : methodObjs) {
            // 如果有MyAnnotate注解,就进行操作,否则不作处理
            if (methodObj.isAnnotationPresent(MyAnnotate.class)) {
                // 获取注解对象
                MyAnnotate annotation = methodObj.getAnnotation(MyAnnotate.class);

                // 获取注解的属性值times
                int times = annotation.times();

                // 根据属性值循环执行该方法
                for (int i = 0; i < times; i++) {
                    methodObj.invoke(stuOpObj);
                }
            }
        }
    }
}

可以看到,没有执行结果。分析:因为注解的保留策略(@Retention)没有设置,默认保留到字节码阶段,运行时丢弃了,故没有达到预期结果。
在这里插入图片描述
查看一下程序的字节码文件
在这里插入图片描述
设置注解保留策略为运行时,再执行一遍

/**
 * 自定义注解
 * @author 10765
 */
// 指定该注解只能用于方法上
@Target(ElementType.METHOD)
// 指定该注解的保留策略为:保留到运行阶段
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotate {
    // 定义属性times,表示次数,默认值为1
    int times() default 1;
}

在这里插入图片描述

最后再试下,保留策略设置为源代码,再运行下查看字节码文件中注解是否还存在

/**
 * 自定义注解
 * @author 10765
 */
// 指定该注解只能用于方法上
@Target(ElementType.METHOD)
// 指定该注解的保留策略为:保留到源码阶段
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotate {
    // 定义属性times,表示次数,默认值为1
    int times() default 1;
}

在这里插入图片描述

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

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

相关文章

案例20:Java物流管理系统设计与实现开题报告

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

ChatGPT全球最大开源平替OpenAssistant:基于Pythia和LLaMA微调而来

论文地址&#xff1a;https://drive.google.com/file/d/10iR5hKwFqAKhL3umx8muOWSRm7hs5FqX/view 项目地址&#xff1a;https://github.com/LAION-AI/Open-Assistant 数据集地址&#xff1a;https://huggingface.co/datasets/OpenAssistant/oasst1 体验地址&#xff1a;http…

Hiredis的基本使用

目录 前言 一.hiredis的安装 二.同步API 2.1.连接Redis数据库 2.1.1 无超时时间&#xff0c;阻塞等待连接 2.1.2 设置超时时间&#xff0c;阻塞等待连接。 2.1.3 非阻塞&#xff0c;不管连接与否&#xff0c;立即返回。 2.2.执行命令 2.2.1 返回执行上下文 2.2.2 没有返回执…

伪类元素的用法总结

1:自闭标签不适用伪类元素 自闭合标签 1. 一般标签   由于有开始符号和结束符号&#xff0c;因此可以在内部插入其他标签或文字。 <p>“绿叶&#xff0c;给你初恋般的感觉。”</p> 2. 自闭合标签   由于只有开始符号而没有结束符号&#xff0c;因此不可以在内…

2023-05-24:为什么要使用Redis做缓存?

2023-05-24&#xff1a;为什么要使用Redis做缓存&#xff1f; 答案2023-05-24&#xff1a; 缓存的好处 买啤酒和喝啤酒的例子可以帮助我们理解缓存的好处。 假设你在超市里买了一箱啤酒&#xff0c;如果你需要每次想喝啤酒就去超市购买&#xff0c;无疑会浪费很多时间和精力…

vue+element纯手工完美模拟实现小米有品网站

一、预览 小米有品官网&#xff1a;小米有品 本作品demo预览地址&#xff1a;点击预览 二、效果图对比 1.官方效果截图&#xff1a; 2.作者实现的demo效果图&#xff1a; 首页&#xff1a; 上新精选&#xff1a; 商品详情&#xff1a; 购物车&#xff1a; 登录&#xff1a; …

【论文阅读】23_SIGIR_Disentangled Contrastive Collaborative Filtering(分离对比协同过滤)

【论文阅读】23_SIGIR_Disentangled Contrastive Collaborative Filtering&#xff08;分离对比协同过滤&#xff09; 文章目录 【论文阅读】23_SIGIR_Disentangled Contrastive Collaborative Filtering&#xff08;分离对比协同过滤&#xff09;1. 来源2. 介绍3. 模型方法3.1…

最小生成树 Prim算法实现(c语言代码)

【问题描述】 城市之间的公路交通可以用一个无向图表示。如下图所示&#xff1a; 顶点表示城市、边表示城市之间有公路相连&#xff0c;边上的权值表示城市之间的公路长度。 编程解决以下问题&#xff1a; &#xff08;1&#xff09;输入城市信息和城市之间公路的信息&…

2023最新SRC漏洞挖掘快速上手攻略!

前言 随着网络安全的快速发展&#xff0c;黑客攻击的手段也越来越多样化&#xff0c;因此SRC漏洞挖掘作为一种新的网络安全技术&#xff0c;也在不断发展和完善。那么&#xff0c;作为一个网安小白如果想要入门SRC漏洞挖掘&#xff0c;需要掌握哪些知识呢&#xff1f;以下是本…

Vue3入门

前言 在Vue 3提供的丰富的基础配置和插件生态系统之下&#xff0c;它是一种适用于多场景开发的前端框架&#xff0c;包括web应用程序、移动应用和桌面应用。使用Vue 3&#xff0c;您可以快速高效构建出具有优秀用户体验的应用程序。 准备工作 首先&#xff0c;我们需要安装V…

运营-15.涉及促销活动的计算原则

1.是否 参与促销活动 如果商品参加促销活动&#xff0c;则在订单结算的时候显示已经参加的活动&#xff0c;否 则不显示&#xff1b; 2.是否 满足促销条件 如果有参加某个活动&#xff0c;则还要判断是否满足活动的条件&#xff0c;比如满200减 10&#xff0c;但是商品价格不足…

spring-cloud-alibaba-seata分布式事务实例

第一步: 首先访问: https://seata.io/zh-cn/blog/download.html 下载我们需要使用的seata1.6.0服务 第二步: 1.在你的参与全局事务的数据库中加入undo_log这张表 -- for AT mode you must to init this sql for you business database. the seata server not need it. CRE…

关于档案室十防环境监控的一些关键内容

档案库房十防监控系统 智慧档案平台/温湿度/空气质量/漏水/视频/门禁/一体化管控平台 HONSOR多维空间可视化智慧档案库房建设一体化平台分享 三维可视化智慧档案馆库房一体化环境安全管控系统平台【相关项目经验图片/相关系统拓展图】【鉴赏】 1、智慧档案馆 2、智慧档案库房…

从零开始之电机FOC控制

我们将撕开FOC神秘而虚伪的面纱&#xff0c;以说人话的方式讲述它。真正的做到从零开始&#xff0c;小白一看就会&#xff0c;一学就废。 如果觉得有用的话&#xff0c;就点个赞呗&#xff0c;纯手码。 一、什么是FOC&#xff1f; FOC是Field Orientation Control的缩写&#…

2023年,千万别裸辞....

作为IT行业的大热岗位——软件测试&#xff0c;只要你付出了&#xff0c;就会有回报。说它作为IT热门岗位之一是完全不虚的。可能很多人回说软件测试是吃青春饭的&#xff0c;但放眼望去&#xff0c;哪个工作不是这样的呢&#xff1f;会有哪家公司愿意养一些闲人呢&#xff1f;…

GaussDB云数据库SQL应用系列-基础使用

目录 一、前言 二、前提条件 1、连接数据库实例 2、GaussDB实例正常运行 三、操作示例 1、选择实例并进入SQL执行界面 2、创建数据库用户 3、创建数据库 4、创建SCHEMA 5、创建表&#xff08;增删改查&#xff09; 1&#xff09;创建3张表&#xff0c;并初始化一些数…

Revit技巧 | 楼梯总画不好?原来是这些技巧你没有掌握

Revit技巧 | 楼梯总画不好&#xff1f;原来是这些技巧你没有掌握 楼梯在我们BIM考试中是重点和难点&#xff0c;根据我们对历年考考题的分析&#xff0c;楼梯部分涉及到的考点为&#xff1a; 栏杆扶手样式的设置&#xff1b; 楼梯踏步数的设置&#xff1b; 楼梯踏板宽度的设…

Adapt Learning使用教程(Adapt Framework/Adapt Authoring)(二)

此文章在上一章的环境配置下操作的&#xff0c;如果还没配置参考我的上一篇文章&#xff1a;Adapt Learning使用教程&#xff08;Adapt Framework/Adapt Authoring&#xff09;&#xff08;一&#xff09; 。环境配置好了之后&#xff0c;就该从GitHub上拉取代码啦&#xff0c…

如何入门Python——学习Python的指南针

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【JOSEF约瑟 应用于输配电路、变压器 JDP-1004双位置继电器 端子排】

名称&#xff1a;双位置继电器&#xff1b;品牌&#xff1a;JOSEF约瑟&#xff1b;型号&#xff1a;JDP-1440&#xff1b;触点容量&#xff1a;250V2A&#xff1b;功率消耗&#xff1a;≤5W&#xff1b;额定电压&#xff1a;220V/110V&#xff1b;外形尺寸&#xff1a;868573特…