局部变量,在使用时再定义

简介: 关于局部变量,适时定义可以提高代码可读性并规避不必要的bug。示例代码中,为了避免误解`checkTaskApplyDTO`仅设置了`userId`,在`existAppliedTask`方法内部,可以通过将`checkTaskApplyDTO`的定义与设置属性的操作靠近,以明确其所有属性值的来源。另外,本文还展示了一个因提前定义变量`ret`而导致的bug实例。如果将此变量的定义延迟至其实际使用前,则可以避免此类问题。适时定义变量有助于减少混淆,提高代码质量。

关于局部变量,适时定义局部变量,可提高代码清晰度和可读性,并能规避不必要的代码bug

局部变量,在使用时再定义,提高代码可读性

下面代码中的2个方法,第1个 verifyTaskApply  调用第2个 existAppliedTask 。 请问,在 existAppliedTask  中调用 taskApplyService.getUserTaskApply 时, checkTaskApplyDTO 有哪些属性值?

private void verifyTaskApply(OrderDetailVO detail,List<UserSignVO> signedList) {
    log.info("收款人任务领取单校验,detailVO:{}", detail);
    if (detail == null || StringUtils.isBlank(detail.getUserIdcardNo()) ||
            detail.getTaskId() == null || detail.getProviderId() == null ||
            detail.getEnterpriseId() == null) {
        log.error("收款人任务领取单校验,参数错误,detailVO:{}", detail);
        throw new VerifyException(VerifyStatusResult.failedWithMessage("收款人任务领取单校验,参数错误"));
    }
    if (CollectionUtils.isEmpty(signedList)) {
        throw new VerifyException(VerifyStatusResult.failedWithMessage("签约记录未获取到"));
    }
    CheckTaskApplyDTO checkTaskApplyDTO = new CheckTaskApplyDTO();
    checkTaskApplyDTO.setProviderId(detail.getProviderId());
    checkTaskApplyDTO.setTaskId(detail.getTaskId());
    checkTaskApplyDTO.setEnterpriseId(detail.getEnterpriseId());
    checkTaskApplyDTO.setProductEnum(ProductEnum.BossKG);
    boolean exists = existAppliedTask(detail, checkTaskApplyDTO,signedList);
    if (!exists) {
        throw new VerifyException(VerifyStatusResult.failedWithMessage("收款人未领取任务"));
    }
}
private boolean existAppliedTask(OrderDetailVO detail, CheckTaskApplyDTO checkTaskApplyDTO, List<UserSignVO> signedList){
    for (UserSignVO signVO : signedList) {
        detail.setUserId(signVO.getUserId());
        detail.setUserSignBankCard(signVO.getUserBankCard());
        checkTaskApplyDTO.setUserId(signVO.getUserId());
        ResultX<TaskApplyVO> result = taskApplyService.getUserTaskApply(checkTaskApplyDTO);
        if (!result.isSuccess() || result.getResult() == null) {
            log.warn("收款人任务领取单校验,未领取任务,taskApplyQuery:{}", checkTaskApplyDTO);
            continue;
        }
        TaskApplyVO taskApplyVO =  result.getResult();
        detail.setTaskApplyId(taskApplyVO.getApplyId());
        detail.setSignId(signVO.getSignId());
        
        if (TaskApplyStatusEnum.TASKAPPLY_PASS == TaskApplyStatusEnum.getBean(taskApplyVO.getApplyStatus())) {
            return true;
        }
        log.warn("收款人任务领取单校验,收款人任务领取单未领取,taskApplyQuery:{}", checkTaskApplyDTO);
    }
    return false;
}


有没有一种可能,你认为checkTaskApplyDTO只给了一个 userId属性值?

如果有,如何消除这种可能的认为”呢?

so easy!下面隐藏的代码,告诉你答案。

private void verifyTaskApply(OrderDetailVO detail,List<UserSignVO> signedList) {
    ...
    boolean exists = existAppliedTask(detail, signedList);
    ...
}
private boolean existAppliedTask(OrderDetailVO detail, List<UserSignVO> signedList){
    CheckTaskApplyDTO checkTaskApplyDTO = new CheckTaskApplyDTO();
    checkTaskApplyDTO.setProviderId(detail.getProviderId());
    checkTaskApplyDTO.setTaskId(detail.getTaskId());
    checkTaskApplyDTO.setEnterpriseId(detail.getEnterpriseId());
    checkTaskApplyDTO.setProductEnum(ProductEnum.BossKG);
    
    for (UserSignVO signVO : signedList) {
        detail.setUserId(signVO.getUserId());
        detail.setUserSignBankCard(signVO.getUserBankCard());
        checkTaskApplyDTO.setUserId(signVO.getUserId());
        ResultX<TaskApplyVO> result = taskApplyService.getUserTaskApply(checkTaskApplyDTO);
        if (!result.isSuccess() || result.getResult() == null) {
            log.warn("收款人任务领取单校验,未领取任务,taskApplyQuery:{}", checkTaskApplyDTO);
            continue;
        }
        ...
    }
    return false;
}



是否依然有一种可能,你认为checkTaskApplyDTO只给了一个 userId属性值?

如果有,如何消除这种可能”呢?

so easy!下面隐藏的代码,告诉你答案。

private void verifyTaskApply(OrderDetailVO detail,List<UserSignVO> signedList) {
    ...
}
private boolean existAppliedTask(OrderDetailVO detail, List<UserSignVO> signedList){    
    for (UserSignVO signVO : signedList) {
        detail.setUserId(signVO.getUserId());
        detail.setUserSignBankCard(signVO.getUserBankCard());
        CheckTaskApplyDTO checkTaskApplyDTO = new CheckTaskApplyDTO();
        checkTaskApplyDTO.setProviderId(detail.getProviderId());
        checkTaskApplyDTO.setTaskId(detail.getTaskId());
        checkTaskApplyDTO.setEnterpriseId(detail.getEnterpriseId());
        checkTaskApplyDTO.setProductEnum(ProductEnum.BossKG);
        checkTaskApplyDTO.setUserId(signVO.getUserId());
        ResultX<TaskApplyVO> result = taskApplyService.getUserTaskApply(checkTaskApplyDTO);
        if (!result.isSuccess() || result.getResult() == null) {
            log.warn("收款人任务领取单校验,未领取任务,taskApplyQuery:{}", checkTaskApplyDTO);
            continue;
        }
        ...
    }
    return false;
}


局部变量,在使用时再定义,规避bug

下图,再一次证明 “变量在使用时再定义” 这句话的正确性。

方法的开头定义了 ret 变量,从这个方法的逻辑,不难看出,这个 ret 是方法的返回值。 而在后面打印日志时,开发者不慎,误将 cardBinDTO 敲成了 ret ,显然,这是一个失误!

如果将 ret 变量的定义延后到 return 语句那块的话,就完全可以规避这个问题。

image.png


目录
相关文章
|
3天前
局部变量和成员变量
局部变量和成员变量 1.定义的位置不一样【重点】 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中 2.作用范围不一样【重点】 局部变量:只有方法当中才可以使用,出了方法就不能再用 成员变量:整个类全都可以通用。 3.默认值不一样【重点】 局部变量:没有默认值,如果要想使用,必须手动进行赋值 成员变量:如果没有赋值,会有默认值,规则和数组一样局部变量和成员变量 1.定义的位置不一样【重点】 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中 2.作用范围不一样【重点】
12 1
|
4月前
|
存储 人工智能 Java
【程序设计】做一个发送系统邮件的功能,如何设计数据表? 转至元数据结尾
重构系统邮件发送旨在实现统一的邮件发送功能,通过公共API提供服务。设计包括两个核心数据表:`mail` 表用于存储邮件基本信息,如邮件ID、业务类型、发送者、标题、内容、附件信息、发送状态和时间戳;`mail_receiver` 表记录邮件接收者信息,包括邮件ID、接收者邮箱、接收者类型、发送状态和重试次数。为了优化查询性能,建议创建`Email_Content`表,将`content`和`attach_file`从`Email`表中分离,以减少主表大小。这有助于提高主表的查询速度,并通过定期的数据结转策略,确保热表只存储最近的数据。
95 0
|
Java
成员变量与局部变量
成员变量与局部变量
115 0
|
5月前
|
缓存 NoSQL 关系型数据库
秒杀项目实战:遇到的问题及解决方案分享
构建了一个基于Springboot2的秒杀系统。项目利用K8S上的主从结构部署Redis和MySQL,通过Traefik作为网关。RabbitMQ在本地虚拟机的docker环境中,用Prometheus+Grafana监控。设计思路包括隐藏秒杀地址以防止脚本攻击,使用Lua脚本保证库存预扣原子性,但初期版本未处理重复订单校验。为防止MQ故障,将订单信息先保存到Redis,再通过脚本发送到MQ。采用分布式锁防止用户重复下单和缓存击穿问题,使用编程式事务确保库存扣减与订单保存一致性。项目通过JMeter测试,观察性能并分析Redis和RabbitMQ的使用情况。完整代码可在GitHub找到。
155 1
秒杀项目实战:遇到的问题及解决方案分享
|
5月前
|
Java Maven 开发工具
记录一次Maven无法打包的排查过程
【5月更文挑战第3天】记录一次WhatTheFuck经历
127 2
记录一次Maven无法打包的排查过程
|
4月前
|
C# Windows
C# 串口关闭时主界面卡死原因分析
串口程序关闭导致界面卡死的原因是主线程与辅助线程间的死锁。问题出在`SerialPort.Close()`方法与`DataReceived`事件处理程序。`DataReceived`事件在`lock (stream)`块中执行,而`Close()`方法会关闭`SerialStream`并锁定自身。当辅助线程处理数据并尝试更新UI时,UI线程因调用`Close()`被阻塞,造成死锁。解决办法是让`DataReceived`事件处理程序使用`this.BeginInvoke()`异步更新界面,避免等待UI线程,从而防止死锁。
|
4月前
|
测试技术 开发者
设计文档中的流程图,靠得住吗?
本文讨论了软件开发设计文档中图形化设计图的重要性,如流程图、思维导图等,它们有助于清晰传达设计意图和提高沟通效率。然而,当面临迭代更新、人员变动时,基于截图的图形设计图可能会带来协作难题。作者提倡使用简单文字格式搭配标签和符号作为替代方案,分享了团队内部实践,通过表格来实现类似思维导图和流程图的功能,以增强文档的可维护性和协作性。同时,作者强调这不是反对使用设计图,而是提出在某些场景下的一种有效补充方法。
110 7
|
3月前
|
监控 网络安全
Connection reset by peer的原因
Connection reset by peer的原因
|
5月前
|
开发者
一键自动化博客发布工具,用过的人都说好(阿里云篇)
使用一键自动化博客发布工具blog-auto-publishing-tools把博客发布到阿里云上。
一键自动化博客发布工具,用过的人都说好(阿里云篇)
|
5月前
|
缓存 算法 NoSQL
短信验证码登录接口,如何防止恶意攻击
该文讨论了移动应用中常见的手机短信验证码登录方式,后端实现通常涉及两个API:获取短信验证码和短信验证码登录。在设计时,为增强短信验证码接口的安全性,提出了几种无需使用Redis等存储介质的方案:1) 使用数字签名,基于时间戳或随机数生成唯一签名进行验证;2) 基于时间的有效期验证,通过加密或修改时间戳形式确保安全性;3) 应用TOTP算法,按时间生成动态码进行比对;4) 利用JWTToken生成带有限期的签名进行验证。这些方法旨在防止恶意攻击并优化登录接口性能。
197 1