代码审查|这段代码,为什么复制文件夹总是“成功”?

最近开始一个人负责整个项目的全栈开发和维护,工作中没了和同事交叉 code review 的环节,所以就打算,如果工作中遇到一些比较典型的代码,包括好味道和坏味道,就拿出来分析下,与大家一起交流,作为另一种形式的「交叉 review」。

这天遇到这样一个问题:在 Android 手机上复制 assets 里的文件夹到手机里,实际并没有拷贝完成,但代码总是显示成功,看了下代码,使用的是阿里云播放器 Android SDK 的 Demo 里的一个工具类。

工具类里的相关代码经过简化后示意如下:

arduino 复制代码
public class Commen {
    private static Commen instance;
    private volatile boolean isSuccess;

    public static Commen getInstance(Context context) {
        // some code here,单例控制,返回 instance
        // ...
    }

    public void copyAssetsToDst(Context context, String srcPath, String dstPath) {
        try {
            String[] fileNames = context.getAssets().list(srcPath);
            if (fileNames.length > 0) {
                for (String fileName : fileNames) {
                    // 文件夹,递归调用
                    copyAssetsToDst(context, srcPath + File.separator + fileName,
                            dstPath + File.separator + fileName);
                }
            } else {
                // some code here,单个文件拷贝
                // ...
            }
            isSuccess = true;
        } catch (Exception e) {
            isSuccess = false;
        }
    }
}

这段代码使用起来若不谨慎,至少存在以下问题:

  1. 线程安全问题:该类是一个单例类,代码中的 isSuccess 相当于是一个全局变量,如果多个线程同时调用 copyAssetsToDst 方法,会出现线程安全问题,导致 isSuccess 的值被交叉覆盖,不可预期;

  2. 结果正确性:因为 Exception 全都被 catch 住了,这样如果 srcPath 是一个文件夹,递归调用方法自身后,最外层总是会将 isSuccess 设置为 true,导致最终结果总是显示成功,而实际结果未知。

如果由我来写这段代码,我会做这样的修改:

  • 将类改为工具类,公开的方法都是静态方法,不需要单例控制;

  • 方法执行是否成功,由返回值、是否抛出异常来表示,不使用成员变量记录;

  • 拷贝过程中,记录拷贝成功的文件列表,如果最终失败,将中间生成的文件做清理。


如果读完文章有收获,可以关注我的微信公众号「闷骚的程序员」并🌟设为星标🌟,随时阅读更多内容。

相关推荐
字节源流5 小时前
关于maven的依赖下不下来的问题
java·maven
pjx9876 小时前
服务间的“握手”:OpenFeign声明式调用与客户端负载均衡
java·运维·spring·负载均衡
prinrf('千寻)6 小时前
MyBatis-Plus 的 updateById 方法不更新 null 值属性的问题
java·开发语言·mybatis
老华带你飞6 小时前
实习记录小程序|基于SSM+Vue的实习记录小程序设计与实现(源码+数据库+文档)
java·数据库·spring boot·小程序·论文·毕设·实习记录小程序
在未来等你7 小时前
互联网大厂Java求职面试:AI与大模型应用集成及云原生挑战
java·微服务·ai·kubernetes·大模型·embedding·spring ai
源码技术栈7 小时前
SaaS基于云计算、大数据的Java云HIS平台信息化系统源码
java·大数据·云计算·云his·his系统·云医院·区域his
编程、小哥哥7 小时前
互联网大厂Java面试:从Spring Boot到微服务架构的技术深挖
java·spring boot·redis·微服务·prometheus·面试技巧
揽你·入怀7 小时前
数据结构:ArrayList简单实现与常见操作实例详解
java·开发语言
okok__TXF8 小时前
SpringBoot3+AI
java·人工智能·spring
AA-代码批发V哥8 小时前
Math工具类全面指南
java·开发语言·数学建模