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

说明:注解可以理解为另一种形式的配置,可用于在类上、方法上等,标志是“@”,如重写方法上的“@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;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一分钟了解乐观锁、悲观锁、共享锁、排它锁、行锁、表锁以及使用场景

大家好&#xff0c;我是冰点&#xff0c;今天给大家带来&#xff0c;关于MySQL中的锁的使用。 我首先提个问题&#xff0c;大家知道什么是 乐观锁、悲观锁、共享锁&#xff0c;、排它锁、行锁、表锁&#xff0c;以及每种锁的使用场景吗&#xff1f; !! 背景&#xff1a;最近在各…

(学习日记)2023.04.23

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

关于安卓以及微软用户chatgpt上一篇文章如今第五点无法正常进入更新解决方法以及附加本地部署

目录 一、问题出现&#xff1a; 1、问题&#xff1a; 原因&#xff1a; 二、解决办法&#xff08;本地部署chatgpt&#xff09; 1、解决&#xff08;国内网络使用真的chatgpt并非镜像&#xff09;一次部署终生使用 第一步&#xff1a; ​编辑第二步&#xff1a; 三、实现结…

让你不再好奇怎么给小说配音

你是否曾经想象过&#xff0c;当你在读小说时&#xff0c;你可以听到人物的声音&#xff0c;感受到情感和气氛的变化&#xff1f;有声书的出现已经让这一切成为可能。然而&#xff0c;如何为小说创造生动的配音效果却是一个需要仔细考虑的问题。如果你还不知道怎么给小说配音的…

智能计价器-第14届蓝桥杯省赛Scratch中级组真题第5题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第140讲。 智能计价器&#xff0c;本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程中级组真题第5题&#…

信号处理与分析-卷积的性质与推导

目录 一、引言 二、信号分析中的卷积 1. 什么是卷积 2. 卷积的性质 3. 卷积的应用 三、离散卷积 1. 离散卷积的定义 2. 离散卷积的计算 3. 离散卷积的性质 四、连续卷积 五、卷积的实际应用 六、总结 一、引言 在信号处理中&#xff0c;卷积是一种非常重要的数学运…

2023年05月小结

5月一晃即将过去&#xff0c;先看看5月份都写了哪些文章&#xff1a; 往期推荐 国内手机号如何注册Google账号 Python中的布尔类型以及布尔值介绍 Python中深拷贝与浅拷贝介绍 Python中的集合介绍 Python中的字典学习笔记 Python学习历程-元组的基本操作回顾 记录我的Python学习…

STM32F103C8T6+2.4寸SPI TFT触摸屏代码+标准库 项目开发

目录 模块清单&#xff1a; 模块介绍&#xff1a; 1&#xff1a;STM32F103C8T6 2&#xff1a;2.4寸SPI TFT触摸屏 项目结果展示 2.4寸 TFT SPI显示触摸屏 2.4寸 SPI TFT 显示触摸屏代码下载链接&#xff1a; (1条消息) 2.4寸SPITFT显示触摸屏资源-CSDN文库 模块清单&#x…

低资源方面级情感分析研究综述

文章目录 前言1. 引言2. 问题定义、数据集和评价指标2.1 问题定义2.2 任务定义2.3 常用数据集 3. 方面级情感分析的方法3.1 **方面词抽取**3.1.1 基于无监督学习的方法3.1.1.1 基于规则的方面词抽取3.1.1.2 基于统计的方面词抽取 3.1.2 基于有监督浅层模型的方法3.1.3 基于有监…

Golang每日一练(leetDay0075) 打家劫舍II、最短回文串

目录 213. 打家劫舍 II House Robber ii &#x1f31f;&#x1f31f; 214. 最短回文串 Shortest Palindrome &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C…

mysql加强小结 203446

数据库三范式: 什么是范式 规则:想要设计一个好的关系,必须要满足一定的约束条件,有几个等级,一级比一级高 ​ 解决什么问题:让数据库设计更加简洁,结构更加清晰,否则容易造成数据冗余 数据库有哪些范式? ​ 数据库有七大范式,常用的只有三个范式 **第一范式:**业务上属…

【1++的C++初阶】之模板

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的C初阶】 文章目录 一&#xff0c;浅谈模板二&#xff0c;函数模板三&#xff0c;类模板 一&#xff0c;浅谈模板 在前面的文章【【1的C初阶】之C入门篇1】中我们对函数重载有了一定的认识&a…

Linux网络服务:SSH远程访问及控制2

目录 一、理论 1.构建密钥对验证的SSH体系 2.TCP Wrappers访问控制 二、实验 1.ecdsa免密连接 2.rsa免密连接 一、理论 1.构建密钥对验证的SSH体系 &#xff08;1&#xff09;免密连接原理 ① 手动添加客户端的公钥到服务端 ② 服务端收到客户端的公钥后使用客户端公钥…

手机充电宝电子充气泵方案

该充气泵产品方案的运行原理是通过电动机将电能转化为机械能&#xff0c;带动电机做往复运动&#xff0c;从而产生大量压缩空气&#xff0c;达到快速充气的效果。该充气泵可用于气垫床、汽车轮胎、自行车轮胎、足球、游泳圈等各类充气物品。产品设计以人性化为主&#xff0c;简…

jQuery其他方法及插件使用

1. 拷贝对象 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width,…

学习c语言中的几道习题(小有难度)!

有兴趣的朋友可以看着题目自己做做&#xff0c;最后在和答案对比&#xff01;相信能力会有所提升的。我现在只是刚刚开始学习c语言&#xff0c;如果有什么说的不对的地方&#xff0c;网路过的大佬&#xff0c;及时予以指正。多谢&#xff01; 1、函数判断闰年 实现函数判断yea…

flowable的流程任务统计sql(续)

继续之前的文章&#xff0c;我们这里还需要进行按月统计&#xff0c;同时为了适应jeecg的图形显示&#xff0c;所以做了一些调整如下&#xff1a; 1、按月统计任务数量 select DATE_FORMAT(c.days, %Y%m) months, count(num) num from (SELECT DATE_FORMAT(START_TIME_, %Y-%m…

Niagara—— Events and Event Handlers

目录 一&#xff0c;Events 二&#xff0c;Event Handlers 多数情况下&#xff0c;系统中的发射器需相互交互&#xff0c;才能创建所需效果&#xff1b;意味着&#xff0c;一发射器生成数据&#xff0c;另一发射器监听该数据&#xff0c;以执行相应行为&#xff1b;在Niagar…

CentOS 系统上安装 Jenkins

#######################注意我这里安装jenkins版本要求实际是要安装jdk11版本的~~~我一开始弄错了 您可以按照以下步骤在 CentOS 上安装 JDK&#xff1a; 1. 首先&#xff0c;打开终端并使用 yum 命令更新系统软件包列表。输入以下命令来执行此操作&#xff1a; sudo yu…

TimSort——最快的排序算法

TimSort——最快的排序算法 排序算法是每个程序员绕不开的课题&#xff0c;无论是大学课程还是日常工作&#xff0c;都离不开排序算法。常见的排序算法有&#xff1a;冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、基数排序等。下面是这些算法性能的概…