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

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

1)常亮提取出来有利于代码阅读,而且下次再做这种判断不用手写或复制,直接通过常量类就能得到,能够避免有的地方是username,有的地方是name来判断同一个逻辑含义相同变量问题。不过我觉得提取出来并不会有利于代码性能提升,因为常量分配在内存的常亮池中,所以内存不会出现多个相同常量字符串。总的来说提取常量主要是为了避免魔法数字和提高代码可读性。

2)常亮定义在final的class中,防止被其它类继承和实例化。至于为什么要在常亮类中定义而不是接口中,,Josh和阿里都没有说明原因,我猜测是单一责任原则,因为接口定义出来是为了让其它类实现的,用不可继承且不能被外部实例化的类可以很好的保证常量的单一性。我又查了一下spring的constant,我发现他是个class,而不是interface

我先自己尝试回答一下,然后再看看stackoverflow和阿里程序员怎么说。
java项目中常量到底该怎么定义_第1张图片
java项目中常量到底该怎么定义_第2张图片

stackoverflow建议用枚举或不能实例化的工具类

阿里文档和常量有关说明:


【推荐】接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的javadoc注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。
正例:接口方法签名:void f();
    接口基础常量表示:String COMPANY = “alibaba”;
反例:接口方法定义:public abstract void f();
说明:JDK8中接口允许有默认实现,那么这个default方法,是对所有实现类都有价值的默认实现

【强制】不允许出现任何魔法值(即未经定义的常量)直接出现在代码中。
反例: String key=”Id#taobao_”+tradeId;
     cache.put(key, value);

【推荐】不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如:缓存相关的常量放在类:CacheConsts下;系统配置相关的常量放在类:ConfigConsts类下。
说明:大而全的常量类,非得ctrl+f才定位到修改的常量,不利于理解,也不利于维护。
【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。
 1) 跨应用共享常量:放置在二方库中,通常是client.jar中的const目录下。
 2) 应用内共享常量:放置在一方库的modules中的const目录下。
    反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“是”的变量:
    类A中:public static final String YES = “yes”;
    类B中:public static final String YES = “y”;
    A.YES.equals(B.YES),预期是true,但实际返回为false,导致产生线上问题。
 3) 子工程内部共享常量:即在当前子工程的const目录下。
 4) 包内共享常量:即在当前包下单独建const目录下。
 5) 类内共享常量:直接在类内部private static final定义。

【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。


阿里尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关。不要在程序中出现魔法数字

总结:java项目中常量要定义一个final类且有私有构造方法,demo代码如下:

public final class PropertiesConstant {
    private PropertiesConstant() {
    }

    public static final String CLIENT_SIG_PC = "pc";
    public static final String CLIENT_SIG_WAP = "wap";

}

你可能感兴趣的:(改善java程序的建议)