利用注解和反射解决代码冗余问题(改进版)

news2025/3/9 10:54:06

在优化代码的时候发现,传参存在着高度冗余,如果后面需要改参数,很不方便。

 String pam1 = "id=" + appKey + "&sign=" + sign + "&method=" + method + "&access_token=" + token + "&timestamp="
                + timestamp + "&projectCode=" + projectCode;

参考网上的方法,自己创建注解类,利用反射注入参数并实现。
在这里插入图片描述
在这里插入图片描述
这里解释一下注解。

  1. @Retention修饰注解,用来表示注解的生命周期
    在这里插入图片描述
    上面三种类型生命周期:SOURCE<CLASS<RUNTIME,使用RUNTIME会包含前面两个生命周期
    那怎么来选择合适的注解生命周期呢?
    首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要 在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife) ,就用 CLASS注解;如果 只是做一些检查性的操作,比如 @Override 和@SuppressWarnings,则 可选用 SOURCE 注解。
    RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
  2. @Target:注解的作用目标
    @Target(ElementType.TYPE)——接口、类、枚举、注解@Target(ElementType.FIELD)——字段、枚举的常量
    @Target(ElementType.METHOD)——方法
    @Target(ElementType.PARAMETER)——方法参数
    @Target(ElementType.CONSTRUCTOR) ——构造函数
    @Target(ElementType.LOCAL_VARIABLE)——局部变量
    @Target(ElementType.ANNOTATION_TYPE)——注解
    @Target(ElementType.PACKAGE)——包
  3. @Inherited:说明子类可以继承父类中的该注解
  4. @Document 是 java 在生成文档,是否显示注解的开关

第二步是创建实体类,并导入注解,定义导出时的字段名(name)和拼接顺序(order)
在这里插入图片描述
第三步就是写出拼接的方法

public class UrlUtil {

    public static String createURL(DeviceDTO deviceDTO){
    deviceUrl deviceUrl = deviceDTO.getClass().getAnnotation(deviceUrl.class);
    StringBuilder stringBuilder = new StringBuilder(deviceUrl.url());
    Arrays.stream(deviceDTO.getClass().getDeclaredFields())
            .filter(x -> x.isAnnotationPresent(deviceField.class))
            .sorted(Comparator.comparing(x -> x.getAnnotation(deviceField.class).order()))
            .peek(x -> x.setAccessible(true))
            .forEach(field -> {
                deviceField flightQueryField = field.getAnnotation(deviceField.class);
        Object value = "";
        try {
            value = field.get(deviceDTO);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (flightQueryField.order() == 1) {
            stringBuilder.append("?").append(flightQueryField.name() + "=" + value).append("&");
        } else {
            stringBuilder.append(flightQueryField.name() + "=" + value).append("&");
        }
    });
    return stringBuilder.toString().substring(0, stringBuilder.toString().length() - 1);
    }
}

如果需要实现传入任意类型的类,可以这样实现:
这里,我的url拼接,不需要?,我把append(?)去掉了,若需要自己加上

 public static <T> String createURL(Class<T> tClass,T cla){
        //将传过来的对象进行赋值处理
        T u = tClass.cast(cla);
        //以下是验证此示意中实体类可被操作了
		//getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
		//.getClass()是一个对象实例的方法,只有对象实例才有这个方法,具体的类是没有的

        for (Field declaredField : u.getClass().getDeclaredFields()) {
            //允许获取实体类private的参数信息
            declaredField.setAccessible(true);
        }
        deviceUrl deviceUrl = cla.getClass().getAnnotation(deviceUrl.class);
        StringBuilder stringBuilder = new StringBuilder(deviceUrl.url());
        //通过自定义注解deviceField获取实体类的字段值和属性值
        Arrays.stream(cla.getClass().getDeclaredFields())
                .filter(x -> x.isAnnotationPresent(deviceField.class))
                .sorted(Comparator.comparing(x -> x.getAnnotation(deviceField.class).order()))
                .peek(x -> x.setAccessible(true))
                .forEach(field -> {
                    deviceField flightQueryField = field.getAnnotation(deviceField.class);
            Object value = "";
            try {
                value = field.get(cla);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if (flightQueryField.order() == 1) {
                stringBuilder.append(flightQueryField.name() + "=" + value).append("&");
            } else {
                stringBuilder.append(flightQueryField.name() + "=" + value).append("&");
            }
        });
        return stringBuilder.toString().substring(0, stringBuilder.toString().length() - 1);
        }

传参的话是这样的
在这里插入图片描述

进行测试
在这里插入图片描述
结果
在这里插入图片描述
这里我没有加前置的url,在实体类的注解里url加上就好了

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

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

相关文章

光隔离器的工作原理及其应用

光隔离器也称为光隔离器或光耦合器&#xff0c;它是一种通过使用光将电信号或电压从一个电路传输到另一个电路的装置&#xff0c;同时它将两个电路彼此隔离。它可以通过隔离过压信号来防止高电压或快速变化的电压损坏组件。光隔离器可以承受高达10KV的输入至输出电压和高达10KV…

html+css+JavaScript+json+servlet的社区系统(手把手教学)

目录 课前导读&#xff1a; 一、系统前期准备 二、前端代码的编写 三、登陆页面简介 四、注册页面 五、社区列表页 六、社区详情页 七、社区发帖页 八、注销 九、访问链接 登陆页面http://175.178.20.77:8080/java106_blog_system/login.html 总结&#xff1a; 课前…

HTML5 <embed> 标签、HTML5 <figcaption> 标签

HTML5 <embed> 标签 实例 被嵌入的 flash 动画片&#xff1a; <embed src"helloworld.swf">尝试一下 浏览器支持 注意: 大多数现代浏览器已经弃用并取消了对浏览器插件的支持&#xff0c;所以如果您希望您的网站可以在普通用户的浏览器上运行&#xf…

【SpringCloud系列】开发环境下重写Loadbalancer实现自定义负载均衡

前言 spring-cloud-starter-netflix-ribbon已经不再更新了&#xff0c;最新版本是2.2.10.RELEASE&#xff0c;最后更新时间是2021年11月18日&#xff0c;详细信息可以看maven官方仓库&#xff1a;https://search.maven.org/artifact/org.springframework.cloud/spring-cloud-st…

【计算机图形学】裁剪算法(逐边裁剪法 Weiler-Atherton裁剪法)

一 实验目的 编写直线段、多边形裁剪算法熟悉逐边裁剪法、Weiler-Atherton裁剪法的使用 4&#xff1a;用逐边裁剪法实现多边形裁剪&#xff08;代码最上方功能区注明是否处理退化边&#xff09; 无退化实验结果如下图所示&#xff1a; 图形初始化&#xff1a;&#xff08;红色…

GaussDB工作级开发者认证—第五章GaussDB数据库操作与管理

一、数据库对象基本操作 查询数据库&#xff1a; postgres# \l --使用元命令查看数据库 postgres# select * from pg_database; --通过系统表查看数据库 表注意事项: 只有表的所有者有权限执行ALTER TABLE命令&#xff0c;系统管理员默认拥有此权限 不能修改分区表的tables…

creator-assetbundle分包

title: creator-assetbundle分包 categories: Cocos2dx tags: [creator, 分包, assetbundle] date: 2023-04-10 15:55:22 comments: false mathjax: true toc: true creator-assetbundle分包 前篇 Asset Bundle 介绍 - https://docs.cocos.com/creator/manual/zh/asset/bundle…

国家出手管人工智能AI了

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 全球都在封杀AI&#xff0c;国家也出手了&#xff0c;人工智能AI的强监管来了!这次反应速度算是很快了。国家出手&#xff0c;AI必须管。 国家网信办拟针对生成式人工智能服务出台管理办法&#…

【万象奥科】RZ/G2UL网关内存压力测试

测试目的 内存压力测试的目的是测试系统内存的稳定性和可靠性&#xff0c;以便确定系统是否能够在各种负载情况下正常运行。其主要目的有&#xff1a; 测试内存的正确性&#xff1a;通过模拟各种内存负载情况&#xff0c;例如写入随机数据、重复写入相同数据、使用指定的模式…

原型模式解读

目录 模式引进问题 原型模式 原型模式原理结构图-uml 类图 原型模式解决克隆羊问题的应用实例 深拷贝和浅拷贝 浅拷贝的介绍 深拷贝基本介绍 重写 clone 方法来实现深拷贝 通过对象的序列化实现实现深拷贝&#xff08;推荐&#xff09; 原型模式的注意事项和细节 模式…

阿里云linux云服务器 安装指定版本node.js

我们在实例管理中找到自己的服务器 然后点击右侧的 远程连接 接着点击理解登录 进入命令窗口 我们在这上面输入 curl -h阿里云的服务器都还是最好会有 curl的 然后 我们输入 sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash下把nv…

带头部表头和侧边表头样式的布局

原型设计的页面中的表格除了头部还有左侧侧边是表头的一个表格&#xff0c;查阅组件文档&#xff0c;发现表格table没有两个表头的布局。 思路&#xff1a; 1、使用div自己布局 2、使用表格table&#xff0c;修改其第一列样式背景&#xff0c;展示除了的样子看着像是有多个表头…

突发!ChatGPT疯了!

‍数据智能产业创新服务媒体——聚焦数智 改变商业今天&#xff0c;笔者正常登录ChatGPT&#xff0c;试图调戏一下他。但是&#xff0c;突然震惊的发现&#xff0c;ChatGPT居然疯了。之所以说他是疯了&#xff0c;而不是崩溃了&#xff0c;是因为他还能回复我&#xff0c;但回…

【计算机网络】1、概念、TCP | UDP | 本地 socket 编程

文章目录一、网络基本概念1.1 端口&#xff08;port&#xff09;1.2 IP 地址 网络地址&#xff08;network&#xff09;和 主机&#xff08;host&#xff09;1.3 子网&#xff08;subnet&#xff09;1.4 子网掩码&#xff08;netmask&#xff09;1.5 保留网段1.6 CIDR 表述形式…

【计算机网络复习】第三章 传输层 3

拥塞 网络边缘主机发送到网络中的负载超出了网络的承载能力&#xff0c;即导致拥塞 u 网络拥塞的特征 时延增大 — 由于在路由器缓存中排队而导致 数据包丢失 — 由于路由器的缓存溢出而导致 u 随着网络负载的增加 传输时延增大 吞吐量下降 拥塞控制&#…

ptuning v2 的 chatglm垂直领域训练记录

thunlp chatglm 6B是一款基于海量高质量中英文语料训练的面向文本对话场景的语言模型。 THUDM/ChatGLM-6B: ChatGLM-6B&#xff1a;开源双语对话语言模型 | An Open Bilingual Dialogue Language Model (github.com) 国内的一位大佬把chatglm ptuning 的训练改成了多层多卡并…

Spring 事务

目录 一、事务简介 二、在Spring中实现事务 编程式事务 声明式事务 三、事务的传播机制 一、事务简介 事务&#xff1a;就是将一组操作封装成为一个整体执行单元&#xff0c;要么全部执行&#xff0c;要么都不执行。 假如事务执行了一半发生了错误就会对已经执行的部分进…

Linux嵌入式学习之Ubuntu入门(三)用户、用户组及文件权限

系列文章目录 一、Linux嵌入式学习之Ubuntu入门&#xff08;一&#xff09;基本命令、软件安装及文件结构 二、Linux嵌入式学习之Ubuntu入门&#xff08;二&#xff09;磁盘文件介绍及分区、格式化等 文章目录系列文章目录用户与用户组创建用户和用户组图形化创建命令创建文件…

【人工智能】— 逻辑Agent、一般逻辑、Entailment 蕴涵、命题逻辑、前向链接、反向链接、Resolution归结

【人工智能】— 逻辑Agent、逻辑智能体Knowledge bases一个简单的基于知识的智能体一般逻辑Entailment 蕴涵Models模型蕴涵与推理命题逻辑逻辑连接词枚举推理有效性可满足性推导和证明霍恩子句Forward chaining 前向链接Proof of completeness&#xff08;完备性&#xff09;Ba…

QT学习开发笔记(项目实战之智能家居物联网项目1 )

智能家居物联网项目 本章介绍使用 Qt 开发智能家居中的一个物联应用。简单直白的说就是通过云服务器远程控 制设备&#xff08;与设备通信等&#xff09;。本章可以直接做毕设&#xff0c;是毕设物联网项目的一大福音&#xff01;本章将实现远 程点亮开发板 LED 作为一个项目实…