java 不要使用魔法值_为什么阿里巴巴Java开发手册中不允许魔法值出现在代码中?...

article/2025/9/8 10:31:58

武培轩

推荐搜索

JavaSpring Boot数据结构MySQLElasticsearchNginx

在阅读《阿里巴巴Java开发手册》时,发现有一条关于关于常量定义的规约,具体内容如下:

a83ff07cea7261dbfef1ca6d793a5523.png

图中的反例是将数据缓存起来,并使用魔法值加链路 id 组成 key,这就可能会出现其他开发人员在复制粘贴的时候,少复制 _ 的情况发生,这种错误很难去检查到,因为读取缓存不存在,可能会去数据库读取,很难察觉到。

如果在生产环境中,大量的请求进来,缓存全部失效,直接请求数据库,导致数据库连接过多,查询效率变低的问题发生,因此看来魔法值确实应该避免出现在代码中。

另外在 《Clean Code》 和 《重构》 等书中也提到了类似的问题,在代码中出现原始形态数字通常来说是坏现象,应该用命名良好的常量类隐藏它。

静态常量取代魔法值

像下面这个例子:

if (billCount > 75) {

//todo

} else {

//todo

}

如果在不了解这块的业务的同事,在读到这块代码的时候,可能会想,75 是什么鬼,为啥和这个数比较,背后深藏着什么秘密吗?可能只有当时的开发人员记得了,导致代码可读性和可维护性极差。

如果声明一个常量,来替换该魔法值,可能就会使代码的可读性和可维护性大大增加。

static final Integer BASIC_BILL_COUNT = 75;

还有些魔法表达式,比如:

if (value > 60 && value <= 80 && type = 1) {

// todo

}

比如这个表达式是表示状态为正常且项目活跃,就可以定义:

boolean isActiveProject = value > 60 && value <= 80 && type = 1;

这样是不是可读性就提高了,一眼就可以看出来这块代码的逻辑。

枚举类取代魔法值

还有一种消除魔法值的方式是使用枚举类代替,下面让我们举个例子:

if (eventId == 1) {

System.out.println("睡觉");

} else if (eventId == 2) {

System.out.println("吃饭");

} else if (eventId == 3) {

System.out.println("打豆豆");

}

如上代码是针对事件 id 去执行相应的事件,如果事件比较少,大家还可以勉强记住每个 eventId 对应的含义,但是随着事件 id 的增多,很可能会发生,新来的员工把事件 id 给搞混了,导致执行错误的事件,发生 bug。

那么我们可以使用枚举类来表示相应的事件:

public enum EventEnum {

/**

* 睡觉

*/

SLEEP_EVENT(1, "睡觉"),

/**

* 吃饭

*/

EAT_EVENT(2, "吃饭"),

/**

* 打豆豆

*/

FIGHT_PEA_EVENT(3, "打豆豆");

private int eventId;

private String desc;

EventEnum(int eventId, String desc) {

this.eventId = eventId;

this.desc = desc;

}

public int getEventId() {

return eventId;

}

public String getDesc() {

return desc;

}

}

修改完之后的代码如下:

if (eventId == EventEnum.SLEEP_EVENT.getEventId()) {

System.out.println("睡觉");

} else if (eventId == EventEnum.EAT_EVENT.getEventId()) {

System.out.println("吃饭");

} else if (eventId == EventEnum.FIGHT_PEA_EVENT.getEventId()) {

System.out.println("打豆豆");

}

是不是可读性急剧提升,还不快看看自己代码中有没有这样的魔法值出现,有的话赶紧改造起来。

还有如果你需要在不同的地点引用同一数值,魔法数会让你烦恼不已,因为一旦这些数字发生改变,就必须在程序中找到所有的魔法值,并将它们全部修改一遍,这样就太费时费力了。

其实不只是 Java 不应该在代码中使用魔法值,其他语言亦是如此。

总结

本文主要介绍了为什么不允许在代码中出现魔法值以及如何将代码中已有的魔法值去除掉。

代码可读性还是比较重要的,你肯定不希望别人在接手你的代码的时候,骂到这数字啥意思,这代码写得跟粑粑一样。

留言讨论

最好的关系就是互相成就,大家的在看、转发、留言三连就是我创作的最大动力。

参考

《Java开发手册》泰山版

fbf1e902b30fdba589bdec1f42e12b45.png

●为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?

●为什么阿里巴巴Java开发手册要求不能轻易修改 serialVersionUID 字段?

●为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?

武培轩

有帮助?在看,转发走一波

喜欢作者


http://chatgpt.dhexx.cn/article/Wiv7CSdV.shtml

相关文章

java 项目减少魔法值_项目代码中魔法值的优雅处理

经常在代码里面会用一些表示有意义的数字&#xff0c;但是如果不写注释的话&#xff0c;过了一段时间我们自己再回去优化代码的时候&#xff0c;可能自己也不清楚这些数字表示的是什么意思了。 如果写注释的话&#xff0c;就要每次使用数字的时候都要写注释了&#xff0c;这样的…

java 魔法值_Java 开发技巧:减少魔法值的使用

1. 前言 重构老代码中遇到了类似这种写法&#xff1a; public void attend(String value){ if ("0".equals(value)) { //todo } else if ("1".equals(value)) { //todo } else { //todo } } 脑壳疼&#xff01;从 Java 语法上无懈可击&#xff0c;但是从业…

IDEA快速去除魔法值

背景 写代码有的时候为了方便&#xff0c;会在代码里面留下很多字符串之类的变量。这种便便会被定义为魔法值。 这种变量正常来讲不影响阅读的。所以一般情况下&#xff0c;我们都不会去处理它。 但是当项目越来越大的时候&#xff0c;我们发现很多地方都有可能使用了同一个…

魔法值与解决办法

1.什么是魔法值 魔法值是指代码中突然出现的数字&#xff0c;之所以称为魔法值&#xff0c;是因为这个20可以有多种意义。在新来的员工接手你的代码时&#xff0c;他们产生疑问&#xff1a;为什么要设这个20&#xff0c;背后有什么秘密吗。大大降低了代码的可维护性。 2.解决办…

java怎么字符连接换行_Java中的换行、转义字符和连接字符-Go语言中文社区

语句输出的换行 我们之前完成了我们的第一个Java输出语句&#xff0c;接下来我们可以做一个简单的输出换行与不换行操作。 例如&#xff1a;我们输出天王盖地虎和宝塔镇河妖 public class Demo1 { public static void main(String[] args) { System.out.println("天王盖地…

java csv 换行_javacsv如何换行输入

javacsv如何换行输入 [2021-02-10 01:25:25] 简介: php去除nbsp的方法:首先创建一个PHP代码示例文件;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推荐:《PHP视频教 java怎么输入换行…

java输出流怎样换行_Java中输出流续写和换行写方法,需要用到的构造方法的知识点...

/* FileOutputStream​(String name, boolean append) 创建文件输出流以指定的名称写入文件。 FileOutputStream​(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。 创建指定File对象表示的文件中写入数据的文件输出流 构造方法的参数: String …

Java输入换行结束

问题出现 &#xff1a; 我在写一个程序的时候&#xff0c;会发现当我想要用while()循环得到一组数字的时候&#xff0c;不加控制条件while()循环就不会停止。 Scanner scanner1 new Scanner(System.in);while(scanner1.hasNext()){System.out.println(scanner1.nextInt());} …

java中的换行

纯copy的 \r return 到当前行的最左边 \n newline 向下移动一行&#xff0c;并不移动左右。 \r\n &#xff08;"\r"&#xff0c;"\n"和"\r\n"&#xff09;&#xff0c;导致输出结果可能出现错误或不一致。建议在代码中统一使用一个…

Java中换行输出的两种方法

效果&#xff1a; 方法一&#xff1a; public class ChairMan{public static void main(String[] args){System.out.printlin("姓名&#xff1a;法外狂徒");System.out.printlin("性别&#xff1a;男");System.out.printlin("家庭住址&#xff1a;北…

Java换行输出的5种方式

///可以在格式化输出类型%n来指定输出一行&#xff0c;其效果等同于println ///println()相当于printf( )&#xff0c;即另起一行输出对应的参数后&#xff0c;再进行一次换行

java常识-java怎么换行

文章目录 "\r"和"\n"的区别"\r"和"\n"的由来回车键和输入的"\n"有不同吗? 系统影响java使用换行符的几种方式 “\r"和”\n"的区别 回车 \r 本义是光标重新回到本行开头&#xff0c;r的英文return&#xff0c;控…

使用一片74LS74实现四分频

1.问题 要求使用一片74LS74搭建四分频电路。 2.74LS74介绍 74LS74是一个集成2个D触发器&#xff0c;可以用作寄存器、移位寄存器&#xff0c;分频计数器等。 分频原理 把 U1 的 ~Q1 输出端接到 D1 输入端&#xff0c; 需要分频的信号输入 时钟信号输入端 CLK1&#xff0c;这…

74LS148+74LS47简易病房呼叫系统电路图

设计目的&#xff1a; (1) 设计一个可供至少6个病房呼叫的简易呼叫系统&#xff1b; (2) 掌握数字电路设计与调试方法&#xff0c;熟悉相应集成电路的使用方法。 设计功能&#xff1a; &#xff08;1&#xff09;至少能满足来自6个病房的呼叫&#xff0c;为每个病房设置呼叫开关…

multisim仿真 74LS147D芯片

multisim仿真 74LS147D芯片

74HC245

一、74hc245简介 74hc245是兼容TTL器件引脚的高速CMOS总线收发器&#xff08;bustransceiver&#xff09;&#xff0c;典型的CMOS型三态缓冲门电路&#xff0c;八路信号收发器&#xff0c;。由于单片机或CPU的数据/地址/控制总线端口都有一定的负载能力&#xff0c;如果负载超…

【Multisim仿真】74LS47译码器驱动共阳数码管显示(0-8)数字显示

【Multisim仿真】74LS47译码器驱动共阳数码管显示&#xff08;0-8&#xff09;数字显示 Multisim仿真演示 74ls47引脚功能 LT&#xff1a; 试灯输入&#xff0c;是为了检查数码管各段是否能正常发光而设置的。当LT0时&#xff0c;无论输入A3&#xff0c;A2&#xff0c;A1&…

【Multisim仿真】74LS90六十进制计数器

【Multisim仿真】74LS90六十进制计数器 Multisim仿真演示 74ls90引脚图及功能 74LS90功能&#xff1a;二&#xff0d;五&#xff0d;十进制异步计数器&#xff08;2 和5&#xff09; A&#xff0e; 将输出QA与输入B相接&#xff0c;构成8421BCD码计数器&#xff1b; B&#…

TI公司TTL/CMOS/LVTTL,74LS/74S/74ALS/74AS/74F/74HC/74HCT/74AC/74ACT/74BCT/74ABT/74LV/74LVC/74LV区别与对比

速率 电平 速率及电平要求 短路电流/输出电阻 输出容量/扇出系数 热阻 来自TI白皮书 Solving CMOS Transition Rate Issues Using Schmitt Triggers Designing With Logic

74ls160/74ls161中文资料介绍

原文&#xff1a;http://www.dzdlt.com/components/2010082728887.html 74LS160 芯片同步十进制计数器&#xff08;直接清零&#xff09; 用于快速计数的内部超前进位 用于n 位级联的进位输出 同步可编程序 有置数控制线 二极管箝位输入 直接清零 同步计数 本电路是由4…