Java—JDK8新特性—重复注解

news2024/11/17 3:38:08

目录

重复注解是什么?

常见的重复注解的应用场景

源码(JDK中哪里?)

在实际开发中哪里使用了注解(举例)

使用步骤

案例


重复注解是什么?

        重复注解,一个注解可以在一个类、方法、字段上同时使用多次

        重复注解的主要应用场景是对同一个元素可以多次使用同一个注解。这种情况下,我们可以使用重复注解来简化代码,提高可读性

常见的重复注解的应用场景

        1.参数校验:重复注解可以用于对方法参数进行校验

        例如,可以定义一个 @NotNull 注解来标记非空的参数,并且可以重复使用该注解来标记多个参数

public void someMethod(@NotNull String param1, @NotNull String param2) {
    // 方法体
}

        2.权限控制:重复注解可以用于标记访问权限

        例如,可以定义一个 @Role 注解来标记用户角色,并且可以重复使用该注解来为某个方法或类指定多个角色

@Role("admin")
@Role("manager")
public void someMethod() {
    // 方法体
}

        3.日志记录:重复注解可以用于标记日志级别

        例如,可以定义一个 @LogLevel 注解来指定日志级别,并且可以重复使用该注解来记录不同级别的日志。

@LogLevel(LogLevel.INFO)
@LogLevel(LogLevel.ERROR)
public void someMethod() {
    // 方法体
}


源码(JDK中哪里?)

        Module java.base

        Package java.lang.annotation

        Annotation Interface Repeatable

package java.lang.annotation;

/**
 * The annotation interface {@code java.lang.annotation.Repeatable} is
 * used to indicate that the annotation interface whose declaration it
 * (meta-)annotates is <em>repeatable</em>. The value of
 * {@code @Repeatable} indicates the <em>containing annotation
 * interface</em> for the repeatable annotation interface.
 *
 * @since 1.8
 * @jls 9.6.3 Repeatable Annotation Interfaces
 * @jls 9.7.5 Multiple Annotations of the Same Interface
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation interface</em> for the
     * repeatable annotation interface.
     * @return the containing annotation interface
     */
    Class<? extends Annotation> value();
}
package java.lang.annotation;

@Documented      
@Retention(RetentionPolicy.RUNTIME) //这个生命周期都有效
@Target(ElementType.ANNOTATION_TYPE)  // 作用注解之上
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation interface</em> for the
     * repeatable annotation interface.
     * @return the containing annotation interface
     */
    Class<? extends Annotation> value();
}


在实际开发中哪里使用了注解(举例)

如Spring中可以使用多个扫描组件来扫描多个包的注解

/
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AliasFor;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
}


使用步骤

01.定义原始注解

02.定义包装注解

03.使用@Repeatable 注解将原始注解 进行包装

04.使用原始注解


案例

01.定义原始注解@Role

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Role {
    String value();
}

02.定义包装注解@Roles

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Roles {
    Role[] value();
}

03.使用@Repeatable 注解将@Role 进行包装

@Repeatable(包装注解.class)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Roles.class) // 使用@Repeatable 注解将 @Role 进行包装
public @interface Role {
    String value();
}

04.使用原始注解,创建UserManager类,创建两个方法createUser()和deleteUser()

public class UserManager {

    @Role("admin1")
    @Role("admin2")
    @Role("admin3")
    @Role("admin4")
    @Role("admin5")
    @Role("admin6")
    public void createUser(String username,String password) {
        System.out.println("User created:" + username);
    }

    @Role("root1")
    @Role("root2")
    @Role("root3")
    @Role("root4")
    @Role("root5")
    @Role("root6")
    public void deleteUser(String username) {
        System.out.println("User deleted:" + username);
    }
}

05.测试类

public class TestDemo {
    public static void main(String[] args) throws Exception{
        UserManager userManager = new UserManager();

        Method createUser = UserManager.class.getMethod("createUser", String.class, String.class);
        Role[] roles = createUser.getAnnotationsByType(Role.class);

        for (Role role : roles) {
            System.out.println("create User Role:" + role.value());
        }
        
        userManager.createUser("Jack","123456");

        Method deleteUser = UserManager.class.getMethod("deleteUser", String.class);
        Role[] DeleteUserRoles = deleteUser.getAnnotationsByType(Role.class);
        for (Role role : DeleteUserRoles) {
            System.out.println("Delete User Role:" + role.value());
        }
        userManager.deleteUser("Jack");
    }
}

输出结果:

create User Role:admin1
create User Role:admin2
create User Role:admin3
create User Role:admin4
create User Role:admin5
create User Role:admin6
User created:Jack
Delete User Role:root1
Delete User Role:root2
Delete User Role:root3
Delete User Role:root4
Delete User Role:root5
Delete User Role:root6
User deleted:Jack

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

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

相关文章

限流式保护器在古建筑消防安全中的应用

安科瑞 华楠 【摘要】我国古建筑众多且具有自身的消防安全特性。本文结合当前古建筑消防安全形势从消防管理、防火设计及火灾扑救三个方面对我国古建筑消防安全问题进行系统的阐述并提出相关对策。 【关键词】古建筑&#xff1b;消防安全&#xff1b;电气防火&#xff1b;限流…

C++ String类的简单实现(非模板)

头文件 #ifndef MY_STRING_H #define MY_STRING_Hclass Mstring {private:int m_length;char* m_pointer;public://构造函数Mstring();//有参构造Mstring(const char* str);//拷贝构造Mstring(const Mstring& obj);//获取长度int length()const;//转换为C字符串const char…

sprinboot 引入 Elasticsearch 依赖包

1.springboot与es的版本有比较强的绑定关系&#xff0c;如果springboot工程引入es的依赖后报一些依赖的错误&#xff0c;那么就看表格中的对应关系&#xff0c;将sprinboot或者es的版本做对应的调整 2.本人是从springboot1.x升级到springboot2.x&#xff0c;做了排包工作 3.升级…

在海外如何通过App Store本地化提高下载量

随着应用市场的应用持续增长&#xff0c;越来越多的应用和游戏占据了全球排行榜的主导地位。因此本地化应用程序商店的展示&#xff0c;对于吸引更多用户并在当今的市场中竞争至关重要。应用程序本地化不仅仅包括简单的翻译&#xff0c;还需要处理内容本身。 1、针对客户使用的…

HummerRisk V1.4.1 发布

HummerRisk V1.4.1发布&#xff1a; 大家好&#xff0c;增加检测整合报告下载&#xff0c;定制多云整合报告并下载PDF&#xff0c;增加K8s 检测规则组&#xff0c;Kubernetes、Rancher、KubeSphere 检测规则组以及规则。新增云账号管理页面关联菜单&#xff0c;新增资源同步日…

C++QT day4

仿照string类&#xff0c;完成myString类 #include <iostream> #include <cstring> using namespace std; class myString {private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度public://无参构造myString():size(10){s…

【力扣每日一题】2023.9.11 课程表Ⅲ

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 今天是和前两天一样课程表&#xff0c;不过今天不太一样了&#xff0c;今天不是图论了&#xff0c;可以看作是全新的题目。 给我们一个课…

Java——选择语句

if语句 语法格式&#xff1a; if(表达式){若干语句 } 例&#xff1a; ​import java.util.Scanner; public class Test1 {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();if(n%20){System.out.println("even");}…

Linux命令200例:write用于向特定用户或特定终端发送信息

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

v2.0舆情分析系统整体功能介绍

登录界面&#xff1a; 1、输入用户名、密码后可正常登录&#xff1b; 2、注册功能点击后进入注册界面正常注册用户信息&#xff1b; 3、忘记密码功能&#xff1a;点击后进入忘记密码页面demo 登录后&#xff0c;进入主页面&#xff0c;主页面目前包含关键词输入功能&#xf…

如何注册哥伦比亚商标?

在当今全球市场竞争激烈的环境下&#xff0c;商标已成为企业的重要资产之一。哥伦比亚作为一个拥有丰富历史文化的国家&#xff0c;对知识产权保护的重视程度也在逐渐提高。通过在哥伦比亚注册商标&#xff0c;企业可以更好地拓展南美市场&#xff0c;并进一步提升品牌价值和知…

Selenium自动化测试 —— 通过cookie绕过验证码的操作

验证码的处理 对于web应用&#xff0c;很多地方比如登录、发帖都需要输入验证码&#xff0c;类型也多种多样&#xff1b;登录/核心操作过程中&#xff0c;系统会产生随机的验证码图片&#xff0c;进行验证才能进行后续操作 解决验证码的方法如下&#xff1a; 1、开发做个万能…

T2I-Adapter:增强文本到图像生成的控制能力

链接&#xff1a;GitHub - TencentARC/T2I-Adapter: T2I-Adapter 文本到图像生成 (T2I) 是人工智能领域的一个重要研究方向。近年来&#xff0c;随着深度学习技术的发展&#xff0c;T2I 技术取得了显著进展&#xff0c;生成的图像在视觉效果上已经与真实图像难以区分。 然而&…

C++ -day3

1、自行封装一个栈的类 头文件 #ifndef ZY1_H #define ZY1_H#include <iostream>using namespace std;class Stack { private:int *p nullptr; //存储栈的数组int top; //栈顶元素的下标int max;public://定义析构函数~Stack();//定义拷贝构造函数…

零基础教程:使用yolov8训练无人机VisDrone数据集

1.准备数据集 1.先给出VisDrone2019数据集的下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1e2Q0NgNT-H-Acb2H0Cx8sg 提取码&#xff1a;31dl 2.将数据集VisDrone放在datasets目录下面 2.数据集转换程序 1.在根目录下面新建一个.py文件&#xff0c;取名叫…

全开源影视APP源码带后台 苍穹影视APP源码 免受权带安装教程

苍穹影视 V20 全新后台七彩视界免受权开源源码此版本为天穹公益版开源无解密安装教程 全新后台很是都雅,源码全开源无加密。 PC 端对接教程&#xff1a; 建议在浮图下操作 正常安装前后端 然后安装米酷 cms 根据教程安装即可 米酷 cms 对接部门已被我改动&#xff0c;只要在安装…

【C++进阶】二叉树进阶之二叉搜索树

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

测试面试回顾(1)

硬件测试面试回顾&#xff08;1&#xff09; pn结MOS和CMOS消耗功耗——MOS器件开关时半导体工艺半导体器件SPSS常用的10种统计分析如何用SPSS进行数据分析&#xff1f;Jmeter介绍及测试用例编写JmeterSelenium测试用例测试用例设计方法通用测试用例八要素自动化运维全局变量与…

matlab自带VMD详解,VMD去噪,VMD分解

为了更好的利用MATLAB自带的vmd函数&#xff0c;本期作者将详细讲解一下MATLAB自带的vmd函数如何使用&#xff0c;以及如何画漂亮的模态分解图。 首先给出官方vmd函数的调用格式。 [imf,residual,info] vmd(x) 函数的输入&#xff1a; 这里的x是待分解的信号&#xff0c;一行或…