大言不惭,则无必为之志。——《论语·宪问》

1、引言

最近在看老大在项目中写的代码,发现在系统常量的定义上,与我之前在开发项目的定义有些不一样,引发了我对系统变量如何规范定义和每一种定义有什么优点?这两个问题的好奇。

为什么需要定义常量?
提取常量主要是为了避免魔法数字和提高代码可读性保证一致性。

首先我想研究下,有哪几种定义常量的方法,经过谷歌,主要有两种:

  • (1)在接口中定义
public interface Constants {static final String URL = "http://baidu.com/";
}
  • (2)在类中定义
public class Constants {public final static String URL = "http://baidu.com/";
}

下面我们就先从这两种方式开始讨论,再去思考哪种方式更适合常量定义。

2、在接口中常量

public interface Constants {static final String URL = "http://baidu.com/";
}

为什么会在接口中定义常量?那是由于在java interface中声明的字段在编译时会自动加上static final的修饰符,即声明为常量。因而interface通常是存放常量的最佳地点。然而在java的实际应用时却可能会产生一些问题。

问题有两个,
(1)第一,是我们所使用的常量并不是一成不变的,而是相对于变量不能赋值改变。例如我们在一个工程初期定义常量∏=3.14,而由于计算精度的提高我们可能会重新定义∏=3.14159,此时整个项目对此常量的引用都应该做出改变。
(2)第二,java是动态语言。与c++之类的静态语言不同,java对一些字段的引用可以在运行期动态进行,这种灵活性是java这样的动态语言的一大优势。也就使得我们在java工程中有时部分内容的改变不用重新编译整个项目,而只需编译改变的部分重新发布就可以改变整个应用。

这部分的细节可参考:https://www.ibm.com/developerworks/cn/java/l-java-interface/index.html

另外,根据单一责任原则,因为接口定义出来主要是为了让其它类实现的,用不可继承且不能被外部实例化的类可以很好的保证常量的单一性。

3、在常量类中定义

public class Constants {public final static String URL = "http://baidu.com/";
}

常量定义在final的class中,防止被其它类继承和实例化。

在阿里巴巴Java开发手册中也对常量定义给出了规范:
1. 【强制】不允许任何魔法值(即未经定义的常量)直接出现在代码中。 反例:String key = “Id#taobao_” + tradeId;
cache.put(key, value);

2. 【强制】long 或者 Long 初始赋值时,使用大写的 L,不能是小写的 l,小写容易跟数字 1 混 淆,造成误解。
说明:Long a = 2l; 写的是数字的21,还是Long型的2?

3. 【推荐】不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。 说明:大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。 正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。

4. 【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包 内共享常量、类内共享常量。
1) 跨应用共享常量:放置在二方库中,通常是client.jar中的constant目录下。 2) 应用内共享常量:放置在一方库中,通常是modules中的constant目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示 “是”的变量:
类A中:public static final String YES = “yes”;
类B中:public static final String YES = “y”; A.YES.equals(B.YES),预期是 true,但实际返回为 false,导致线上问题。
3) 子工程内部共享常量:即在当前子工程的constant目录下。
4) 包内共享常量:即在当前包下单独的constant目录下。
5) 类内共享常量:直接在类内部private static final定义。

5. 【推荐】如果变量值仅在一个范围内变化,且带有名称之外的延伸属性,定义为枚举类。下面 正例中的数字就是延伸信息,表示星期几。
正例:public Enum { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);}

13.【推荐】接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁 性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是 与接口方法相关,并且是整个应用的基础常量。

4、推荐做法

public final class Constants {private Constants(){} public static final String URL = "http://baidu.com/";
}

上面的写法主要考虑以下几点:
(1)class的类型为final,表示该类是不可以继承的;
(2)定义了一个私有的构造函数,避免实例化该类;
(3)常量的类型为public final static,static修饰的属性的初始化在编译期(类加载的时候),初始化后能改变。final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变。static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问;

java项目中常量规范定义的思考相关推荐

  1. java项目中常量到底该怎么定义

    背景:由于最近要接手一个老的系统,在看代码逻辑的过程中,看到程序中有很多魔法数字,所以着手把系统中的常量单独提取出来,然后定义在常量类中.本来这样就可以完工了,可是我有俩疑问: 1,为什么要将常亮提取 ...

  2. java接口如何定义常量 c_在Java接口中怎样访问定义的常量呢?

    java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能).那么我们在Java接口中怎 ...

  3. java 接口中 常量_在Java接口中怎样访问定义的常量呢?

    java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能).那么我们在Java接口中怎 ...

  4. java项目怎么定义异常_在Java项目中如何实现自定义异常

    在Java项目中如何实现自定义异常 发布时间:2020-11-11 15:41:32 来源:亿速云 阅读:77 作者:Leah 这篇文章将为大家详细讲解有关在Java项目中如何实现自定义异常,文章内容 ...

  5. 浅谈Java项目中要不要使用实体类

    问题背景:   经过在学校的努力学习,2021届菜鸟毕业喽.终于踏上了接受社会毒打的历程,毕业后入职第一家公司,欢天喜地的打开项目准备写下毕业后的第一套增删改查,然后emmmmmmm   公司的项目中 ...

  6. Ant在Java项目中的使用(一眼就看会)

    参考:http://www.cnblogs.com/zhengqiang/p/5557155.html Ant是跨平台的构建工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将A ...

  7. 为什么我会在2012年的新企业Java项目中使用Java EE而不是Spring

    这个问题经常出现. 我的新项目也在2011年11月发布. 在这个新的Enterprise Java项目中,我将使用Java EE(JEE)代替Spring框架. 我知道:关于此主题的文章,博客和论坛讨 ...

  8. java 代码造假_老板居然让我在Java项目中“造假”

    1. 前言 老板说,明天甲方要来看产品,你得造点数据,而且数据必须是"真"的,演示效果要好看一些,这样他才会买我们的产品,我好明年给你换个嫂子.一般开发接到这种过分要求都不会很乐意 ...

  9. jfinal 普通java工程_JFinal getModel方法如何在java项目中使用

    JFinal getModel方法如何在java项目中使用 发布时间:2020-11-17 15:11:27 来源:亿速云 阅读:94 作者:Leah 今天就跟大家聊聊有关JFinal getMode ...

最新文章

  1. 计算机编程语言python-初学者最容易学的六种编程语言
  2. php中mysqli_query,在PHP中如何使用mysqli_query()函数
  3. 【采购订单】利用BAPI创建PO后丢失消息输出
  4. tomcat跳转报错_微信小程序开发:使用reLaunch跳转时报错的解决步骤
  5. Git本地仓库管理远程库(GitHub)——clone(下载)、push(提交)、pull(拉取)操作
  6. linux jdk1.7 tomcat mysql_Linux环境搭建 jdk+tomcat+mysql
  7. cmake 安装mysql5.6_使用cmake在CentOS6.5安装MYSQL5.6
  8. Excel不好吗?为什么非要用Python做数据分析
  9. cloudMusic.mps的前世今坑
  10. 论文被多人研究过了,我还可以怎么写?
  11. 计算机怎么建我的文档,如何修改我的文档路径
  12. 深圳市已获取支付牌照公司
  13. [TODO]高维空间求近似最近邻
  14. 国防科技大学计算机考研资料汇总
  15. 【面试题记录】2020前端秋招笔试面试题目记录
  16. 微内核相对于单内核优势之我见
  17. 主线程和子线程下的事务不回滚【spring】
  18. P1247 取火柴游戏 (博弈论)
  19. MES系统到底是什么?
  20. 涂鸦Wi-FiBLE SoC开发幻彩灯带(6)----幻彩灯带功能演示

热门文章

  1. jQuery实现拉勾穿墙效果
  2. Debian配置登陆欢迎信息
  3. 什么是智能工业相机?
  4. 【案例分享】菊风云 | Watch!儿童手表实现视频通话,竟如此简单!
  5. Mysql导入数据库时报错ERROR: Unknown command '\0'
  6. 把Excel表格通过MySql Workbench导入数据库表中的使用总结
  7. python画日漫_豆瓣9.3分,日漫风格的机器学习数学书
  8. Ubuntu 玩机笔记
  9. Linux基本命令用法(最基本的emmm)
  10. 标量除、矢量除、正交化