Java知识点整理 17 — 消灭魔法值

一. 什么是魔法值

魔法值通常是指在编写代码时凭空出现的数字或字符串,如果没有注释,无法直接判断其代表的含义,必须通过分析代码上下文才能明白。

魔法值会严重降低代码可读性与可维护性。在一个周期相对较长的项目中,很可能后续在回顾之前编写的代码时忘记这类魔法值代表的含义,如果没有注释或批注,将严重影响开发进度。个人项目亦是如此,更何况别人的项目代码。

例如:

gender.setGender(0); // 设置性别为女
gender.setGender(1); // 设置性别为男statu.setStatus(0); //表示状态正常
statu.setStatus(1); //表示状态异常……

阿里巴巴 Java 开发规范手册中明确指出:不允许任何魔法值(即未经定义的常量)直接出现在代码中。

二. 魔法值替换

1. 常量

使用 public static final 修饰的成员变量,必须有初始化值,且一旦被初始化,执行过程中值将不可变。通常使用英文单词全部大写,多个单词之间使用下划线连接。

// 标识用户性别
public class UserGender {// 0 代表女性public static final Integer USER_GENDER_FEMALE = 0;// 1 代表男性public static final Integer USER_GENDER_MALE = 1;}// 标识用户状态常量
public class UserStatus {// 0 代表正常 public static final Integer USER_NORMAL  = 0;// 1 代表异常public static final Integer USER_ABNORMAL  = 1;// 2 代表禁止public static final Integer USER_PROHIBIT  = 2;
}

在使用常量时,Java 会在编译阶段自动进行替换,将常量替换成真实的字面量。

// 使用常量 UserGender.USER_GENDER_MALE
System.out.println(UserGender.USER_GENDER_MALE);
// java会在编译阶段替换为字面量 1
System.out.println(1);

在业务中具体使用时可以显著提高代码可读性,如果想要修改值,在 UserGender 类中修改即可,所有引用处都会生效。

// 使用魔法值
user.setGender(0);// 使用常量
user.setGender(UserGender.USER_GENDER_FEMALE);

2. 枚举类

通过枚举类,开发者可以固定要接收的常量数值,适合需要约束接收值的场景。

对于相对简单的场景,直接使用枚举示例:

// 协议状态枚举
public enum ProtocolMessageStatusEnum {OK, // 请求成功BAD_REQUEST, // 请求失败BAD_RESPONSE; // 响应失败}

使用时直接调用,但只能获取事先罗列的枚举类实例:

public class Test {public static void main(String[] args) {System.out.println(ProtocolMessageStatusEnum.OK);System.out.println(ProtocolMessageStatusEnum.BAD_REQUEST);System.out.println(ProtocolMessageStatusEnum.BAD_RESPONSE);}
}

在相对复杂的场景中,可以给每个实例增加一个或多个值。

例如在 RPC 项目实现自定义协议部分,曾创建响应状态的枚举类:

import lombok.Getter;/*** 协议消息的状态枚举*/
@Getter
public enum ProtocolMessageStatusEnum {OK("ok", 20),BAD_REQUEST("badRequest", 40),BAD_RESPONSE("badResponse", 50);// 可以有多个字段private final String text;private final int value;// 必须提供对应参数构造器ProtocolMessageStatusEnum(String text, int value){this.text = text;this.value = value;}/*** 根据 value 获取枚举** @param value* @return*/// 开放获取实例值权限public static ProtocolMessageStatusEnum getEnumByValue(int value){for (ProtocolMessageStatusEnum anEnum : ProtocolMessageStatusEnum.values()){if (anEnum.value == value){return anEnum;}}return null;}
}

在使用时可以直接调用,并且多了自定义方法,getEnumByValue:

header.setStatus((byte) ProtocolMessageStatusEnum.OK.getValue());……eader.setSerializer((byte) ProtocolMessageSerializerEnum.getEnumByValue( …… );

当我们将枚举类应用在方法参数列表中,那就有很强的约束性。此外,如果对于一些方法只能接受数值,还可以通过 values 获取所有值,然后判断数值的正确性。

public class App {public static void main(String[] args) {setStatus(UserStatusEnum.NORMAL);}public static void setStatus(UserStatusEnum userStatus){// 判断参数是否为对于枚举实例if(isTrueValue(status)){User user = new User();user.setStatus(status);} else {Syetem.out.println("非法参数");}// 判断参数是否为对于枚举实例public static boolean isTrueValue(Integer num) {UserStatusEnum[] values = UserStatusEnum.values();for (UserStatusEnum statusEnum : values) {Integer value = statusEnum.getValue();if (value.equals(num)) {return true;}}return false;}
}

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

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

相关文章

隐私信息管理体系认证:守护个人信息,筑牢隐私防线

在数字化浪潮汹涌的当下,个人信息安全问题愈发凸显其重要性。随着互联网技术的飞速发展,我们的隐私信息如同裸露在阳光下的沙滩,稍有不慎就可能被不法分子窃取或滥用。因此,构建一个完善的隐私信息管理体系,成为了保障…

UI(四)布局

文章目录 10、Navigator——路由器组件11、Pannel——可滑动面板12、Refresh——刷新组件13、RelativeContainer——相对布局组件14、Scroll——可滚动容器15、SideBarContainer——侧边栏容器16、Stack——堆叠容器17、Swiper——滑动块视图容器18、Tabs和TabContent——页签和…

vue为啥监听不了@scroll

哈喽 大家好 我在vue中写了一个滚动scroll监听事件 然后滚动鼠标 发现进不来我的方法断点 原因: 事件绑定错误:确保你使用scroll正确绑定到了可滚动容器上。 事件冒泡:滚动事件可能被封装在某些组件内部,导致不会冒泡到父元素上…

鸿蒙开发Ability Kit(程序访问控制):【使用粘贴控件】

使用粘贴控件 粘贴控件是一种特殊的系统安全控件,它允许应用在用户的授权下无提示地读取剪贴板数据。 在应用集成粘贴控件后,用户点击该控件,应用读取剪贴板数据时不会弹窗提示。可以用于任何应用需要读取剪贴板的场景,避免弹窗…

Android中的适配器,你知道是做什么的吗?

😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD,日常还会涉及Android开发工作。 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起…

时间复利效应才是人生的催化剂

在追求成功的道路上,许多人都在寻找捷径。然而,真正的捷径并非不劳而获的幻想,而是通过长期坚持在某一领域深耕细作,享受时间复利效应带来的巨大收益。本文将探讨如何选择合适的领域并长期坚持下去,以实现成功。 时间…

DpEasy社区版1.4.1 | 针对托管账号进行功能完善

DpEasy 数据库特权账号管理平台社区版 1.4.1 已上线! 本次版本,主要针对托管账号做了新增功能和部分优化。具体如下: | 支持密码纠正 当出现 DpEasy 平台上的托管账号密码与实际账号密码不一致的情况,可以通过「密码纠正」进行…

如何养成爱自己的习惯:吸引世间美好,改变命运

在这个快节奏、高压力的时代,我们常常被各种事务所困扰,内心难以得到真正的宁静。然而,古老的智慧告诉我们,“静”是宇宙万物的根源,是生命恢复的根本。本文将探讨如何养成“静”的习惯,从而吸引世间美好&a…

Elasticsearch集群部署(上)

目录 前言 一. 环境准备 二. 实施部署 三. 安装配置head监控插件 (只在第一台es部署) 四. Kibana部署(当前还是在第一台es部署) 五. 安装配置Nginx反向代理 六. Logstash部署与测试 前言 1. Elasticsearch: 是…

邦芒支招:职场上令你升职加薪的四个能力

身在职场,我们都想升职加薪,获得成功,但是真正能达到的凤毛麟角,我常常告诉我的下属,想要升职你最少要必备的四个能力,小邦跟大家分享一些经验。 1、明确需要,制定目标,让领导知道你…

智慧公厕系统改变了人们对服务区公厕的看法

在过去,服务区公厕常常给人留下脏乱差的印象,成为人们在长途旅行途中不愿停留的地方。然而,随着智慧科技的不断发展和应用,智慧公厕系统的出现改变了人们对服务区公厕的看法,为公共卫生设施的提升注入了新的活力。 一、…

YOLOv8-对注意力机制模型进行通道剪枝-同时实现涨点和轻量化【附代码】

文章目录 前言视频效果文章概述必要环境一、训练自己的模型1、 训练命令2、 训练参数解析 二、模型剪枝1、 对训练好的模型将进行剪枝2、 剪枝代码详解1.解析命令行参数2. 定义剪枝函数3. 定义剪枝结构4. 更新注意力机制5. 保存更新后的模型6. 主函数 三、剪枝后的训练运行命令…

【日常记录】【JS】动态执行JS脚本

文章目录 1、第一种方式:eval2、第二种方式:setTimeout3、第三种方式:创建script 标签插入body4、第四种方式:创建 Function5、对比6、 参考链接 1、第一种方式:eval 语法 eval(string)参数 string:一个…

获取目标机器的ssh反弹权限后,如何通过一台公网服务器的服务 jar 包进行偷梁换柱植入目录进行钓鱼,从而获取目标使用人的终端设备权限和个人信息?

网络攻防实战中获取目标机器的ssh反弹权限后,如何通过一台公网服务器的服务 jar 包进行偷梁换柱植入目录进行钓鱼,从而获取目标使用人的终端设备权限和个人信息? 具体流程如下: 1)获取了目标用户经常访问的一台服务器信息,并能反弹shell回来进行远程ssh链接; 2)分析…

CenteOs7上安装Redis

CenteOs7上安装Redis 安装前先检查安装环境开始安装下载fedora的 epel 仓库安装redis数据库启动与检查状态命令启动redis停止redis查看redis运行状态查看redis进程 设置开机启动修改配置如果你觉得麻烦,使用一下配置录入以下内容 最后请放开端口允许连接 参考文章 安…

python获取字符编码

在Python中,您可以使用内置的ord()函数获取单个字符的Unicode编码,使用encode()方法获取字符串的字节编码。 获取单个字符的Unicode编码: char a unicode_code ord(char) print(unicode_code) # 输出字符的Unicode编码 获取字符串的字节编码: tex…

Linux指定文件权限的两种方式-符号与八进制数方式示例

一、指定文件权限可用的两种方式: 对于八进制数指定的方式,文件权限字符代表的有效位设为‘1’,即“rw-”、“rw-”、“r--”,以二进制表示为“110”、“110”、“100”,再转换为八进制6、6、4,所以777代表…

Android 11.0 SettingsProvider 源码分析

文章目录 一、SettingsProvider 的概述二、SettingsProvider 的启动流程三、对 SettingsProvider 进行操作方法四、客制化示例 一、SettingsProvider 的概述 SettingsProvider 是一个为 Android 系统设置提供数据共享的 Provider,它包含全局、安全和系统级别的用户…

kafka集群单独开启kerberos详细步骤

Kafka 2.8新特性 可以不使用zk。使用自我管理的仲裁机制。 增加describe集群的API。 支持SASL、SSL双向TLS身份认证。 根据IP,限制broker connection的创建速率。 JDK 1.8 zookeeper(可以使用DP的zk,但需指定zk的namespace,避免跟…

配置WLAN 示例

规格 仅AR129CVW、AR129CGVW-L、AR109W、AR109GW-L、AR161W、AR161EW、AR161FGW-L、AR161FW、AR169FVW、AR169JFVW-4B4S、AR169JFVW-2S、AR169EGW-L、AR169EW、AR169FGW-L、AR169W-P-M9、AR1220EVW和AR301W支持WLAN-FAT AP功能。 组网需求 如图1所示,企业使用WLAN…