在对Java和Groovy代码进行的各种代码审查中,我经常看到魔术数字和其他随机字符串在整个代码库中乱七八糟。

例如,魔术数字是下面的代码(Groovy)中的4.2:

if (swashbuckle >= 4.2) {...
}

4.2是什么意思?

我的建议是将一个数字提取为一个常数,并为其赋予一个有意义的意图显示名称,以便我们所有人都可以继续理解我们的代码。

重构成

if (swashbuckle >= MAX_ALLOWED_CAPACITY) {...
}

即使是初学者,也可以理解The Constant的值,并开始将各地的值提取为常量。 当我谈论枚举时,编写可读代码甚至更有可能,但是经验不足的开发人员很快就会陷入以下陷阱。

陷阱#1全球Über-Constants文件

应尽可能避免使用全局常量文件,例如

class Constants {private static final String PEACH_FLAME = "PFL"private static final int MAX_TOOGIT = 17private static final int MIN_TOOGIT = 8private static final String USER_NAME_AGE_PROPERTY =  "age"private static final String USER_NAME_FLOPPY_PROPERTY =  "floppy"private static final int CUSTOM_HYSLERIA_DONE = -99private static final List<String> WOBBA_RANGE = ['BZ, 'FLL', 'BZZ']// dozens of other constants...

引用StackOverflow总结得很好 :

我强烈建议不要使用单个常量类。 当时这似乎是个好主意,但是当开发人员拒绝记录常量并且该类增长到包含多达500个完全不相关的常量(与应用程序的完全不同的方面)时,这通常会变成完全不可读的常量文件。 代替:

  • 如果可以访问Java 5+,请使用枚举为应用程序区域定义特定的常量。 对于这些常量,应用程序区域的所有部分都应引用枚举,而不是常量。 您可以声明类似于声明类的枚举。 枚举也许是Java 5+的最(也是唯一的)有用的功能。
  • 如果您的常量仅对特定类或其子类之一有效,则将其声明为protected或public,然后将其放在层次结构中的顶级类上。 这样,子类可以访问这些常量值(如果其他类通过public访问它们,则这些常量不仅仅对特定的类有效……这意味着使用该常量的外部类可能与包含该常量的类紧密耦合。常数)
  • 如果您有一个定义了行为的接口,但是返回值或参数值应该是特定的,那么在该接口上定义常量是完全可以接受的,以便其他实现者可以访问它们。 但是,请避免创建仅用于保存常量的接口:它可能与仅为保存常量而创建的类一样糟糕。

一个类(例如上面的Constants示例)很快就变成了一切 。 新秀开发人员认为他通过将魔术数字和魔术字符串提取为常量来遵循良好的(代码审查)建议,但是团队很快就承担了新的维护负担。

如果你发现自己(或你的团队)这样做,请把负责任的车主如用户相关的常数常量UserService在和wobba相关常量WobbaConverter -不管它是什么

还请阅读上面评论中有关枚举的部分,因为常量并不是镇上唯一的孩子。 有时我的建议是……

首选枚举

如果您的常量可以很好地建模为枚举,请考虑枚举结构。 枚举比普通常量更通用 ; 它们是类,可以包含属性和方法。

在负责任的父类中。

更喜欢

class Person {enum Gender { M, F }String nameGender gender
}

过度

class Person {static final String GENDER_MALE = 'M'static final String GENDER_FEMALE = 'F'String nameString gender
}

或作为使用它的班级附近的一个单独的班级 (如果它变大了)。 带有功能名称的enum类的一个很好的例子是例如一些相关的(技术)数据

/*** Represents medicine domain codes.*/
public enum MedicineCode {/** Diagnosis e.g. "Muscle damage". */DIAGNOSIS("X357"),/** Units in medicinal context e.g. "cc/ml". */MEDICINE_UNIT("X523"),/*** Cause codes for diagnosis = 'Masitis' e.g. "E.coli (ECO)".*/CAUSE_CODE("X536"),/** TreatmentType e.g. "Antibiotics". */INTERVAL_TYPE("X520"),
MedicineCode(String code) {this.code = code;}private final String code;public String code() {return code;}/*** Find a {@link MedicineCode} by given String code.** @param code The code e.g. "X261"* @return found medicine code, or null*/public static MedicineCode findByCode(String code) {values().find { it.code() == code }}@Overridepublic String toString() {return name() + "(" + code() + ")"}
}

每当需要表示一组固定的常量时,都应使用枚举类型。 因此,新秀开发人员认为他通过遵循一些很好的(代码审查)建议,将内容提取到枚举中,封装了技术数据,使用功能名称等,但通常会陷入

陷阱#2定义枚举,并非真正正确地使用它们

因此,如果您最初具有以下方法和调用:

Medicine findMedicineForDomainCode(String code)// which you call like:
String intervalTypeCode = "X520"
findMedicineForDomainCode(intervalTypeCode)

并且您可能会引入像MedicineCode这样的枚举(请参见上文),将所有这些特定于域的技术代码(例如数据库“ X…”)(例如“ X520”)封装在一起,然后不要这样做:

Medicine findMedicineForDomainCode(String domainCode)// which one keeps calling like:
String intervalTypeCode = MedicineCode.findByCode("X520")
findMedicineForDomainCode(intervalTypeCode)

我见过像这样的团队。 是的,有一个带有值的枚举类型,但是团队在整个代码中并不十分了解如何处理它们。

第一步是直接引用枚举 。 某些菜鸟开发人员通常最初已经理解了这一点,这取决于他们是否遵循Oracle Java Enum Types教程或类似内容,但是通常会导致如下所示:

Medicine findMedicineForDomainCode(String code)// which one calls like:
String intervalTypeCode = INTERVAL_TYPE.code()
// WRONG! still using Strings here
findMedicineForDomainCode(intervalTypeCode)

有了枚举意味着我们现在可以键入所有内容,包括返回类型和方法参数

只是将枚举用作容纳字符串的容器并不是我们这样做的原因:为了获得更好的类型安全性和可读性,您应该重构代码中的所有内容,以便将域代码用作MedicineCode枚举的字符串类。

更好:

// first refactor method parameter from String to MedicineCode
Medicine findMedicineForDomainCode(MedicineCode code)// now just pass an enum value
findMedicineForDomainCode(INTERVAL_TYPE)

然后,直到那时,在最后一个可能的时刻,您需要实际的封装String代码(“ X520”)–可以从枚举值中提取出它。

希望这有助于定义常量和使用枚举。 对于适当设计的枚举类型,我无法涵盖所有​​其他可能的“有效”用法和OO优势场景,但是希望本文能够防止Java新手陷入所描述的陷阱。

翻译自: https://www.javacodegeeks.com/2016/04/2-rookie-java-constants-enums-pitfalls.html

2个菜鸟Java常量和枚举陷阱相关推荐

  1. java 枚举 菜鸟_2个菜鸟Java常量和枚举陷阱

    java 枚举 菜鸟 在对Java和Groovy代码进行的各种代码审查中,我经常看到魔术数字和其他随机字符串散落在整个代码库中. 例如,下面的(Groovy)代码段中的4.2是一个神奇的数字: if ...

  2. JSP 调用java 常量 枚举

    JSP 调用java 常量 枚举 JAVA:public enum ReimStatus {UNCONFIRMED ("118001"), //未确认 DISPATCH_VERIF ...

  3. 用好 Java 中的枚举,让你的工作效率飞起来!

    1.概览 在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式. enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承j ...

  4. 用好 Java 中的枚举,真的没有那么简单!

    1.概览 在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用  Java 枚举实现一些设计模式. enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承 ...

  5. java基础(十一) 枚举类型

    枚举类型Enum的简介 1.什么是枚举类型 枚举类型: 就是由一组具有名的值的有限集合组成新的类型.(即新的类). 好像还是不懂,别急,咱们先来看一下 为什么要引入枚举类型 在没有引入枚举类型前,当我 ...

  6. java中的枚举类_java中的枚举类型

    java中为了对参数类型使用限定,引入了泛型,实现了在编译期对参数类型是否合法的判断.同样,java为了对参数的值的限定,引入了枚举类,实现了在编译期对参数的值是否合法的判断. 首先我们用自定义类的方 ...

  7. java.lang包—枚举类Enum

    原文作者:山高我为 原文地址:java enum的用法详解 目录 一.enum关键字 二.Enum类源码 三.疑问 四.Enum常见用法 一.enum关键字 enum关键字是在Java1.5也就是Ja ...

  8. java单例枚举_Java增强枚举的用例

    java单例枚举 Brian Goetz在消息" 增强枚举-用例 "中写道:"我们希望就现在实现的功能[ 增强枚举 ]获得用户反馈." 他陈述了他的消息的第一个 ...

  9. Java基础笔记 – 枚举类型的使用介绍和静态导入

    Java基础笔记 – 枚举类型的使用介绍和静态导入 本文由 arthinking 发表于404 天前 ⁄ Java基础 ⁄ 暂无评论 ⁄ 被围观 1,433 views+ 1.枚举(Enum): JD ...

最新文章

  1. java二级考试历年真题6_2018年3月计算机二级考试JAVA试题及答案(六)
  2. 嵌入式linux下如何尽快播放开机音乐
  3. php留言簿代码,php自治简单留言板代码
  4. Spring 杂谈.
  5. easyui中获取getEditor为空情况
  6. TypeScript的class关键字
  7. 2、Sprite,SpriteBatch,Texture,TextureRegion的初步认识
  8. 山东外贸职业学院王彩霞老师网上考试系统及c语言考试题库》,2015年山东外贸职业学院单招考试内容...
  9. mysql非必现数据插不进去_MySQL必知必会:数据插入(Insert)
  10. CSS超过指定的宽度加省略号
  11. 【专访】首届腾讯社交广告“高校算法大赛”落幕 冠亚季军团队参赛心得精彩分享
  12. 聚能聊每周精选 第十五期
  13. vue自定义全局组件(或自定义插件)
  14. Linux系统Bash(Shell)基础知识(4)
  15. CSS | 使用 PostCSS 插件让 Web 应用支持暗黑模式
  16. 北美电影票房Top10-2019年12月27日:《小妇人》表现亮眼
  17. PDF打开不能打印什么原因呢
  18. tp点一共有多少_dnf人家为什么比你多好几点tp点?原因终于找到啦
  19. 正负数在计算机中的表示(原码反码补码)及位运算
  20. 百度工程师带你探秘C++内存管理(理论篇)

热门文章

  1. JSON Web Token (JWT)生成Token及解密实战
  2. 致我们最最最最最最最最最最最最最优秀的班主任——王老师
  3. 把Springboot项目部署到服务器上和结束运行
  4. Java开发利器:IntelliJ IDEA的安装、配置与使用
  5. android 按键消息,在android中模拟键盘消息(shell命令的方法)
  6. df、du和fdisk命令的区别
  7. HDU2612(BFS算法)
  8. 小程序真机测试错误代码_测试不充分:知道您的代码是否真的可以投入生产的5种方法...
  9. selenium编写脚本_Selenium脚本编写技巧和窍门
  10. java 常规类的可见性_Java 12常规可用性