本文针对面向对象语言(以Java为例)中常量定义的几种常见方法做一个总结和简单比较。

常见的常量定义方式主要有以下几种:

第一种:使用接口定义常量

定义方法如下:

package com.shansun.staticex;
public interface BadIrrationalConstants {
     public static final double SQRT_TWO = 1.414;
     public static final double SQRT_THREE = 1.732;
}如果你想在自己的类中使用这些接口中定义的常量的时候,那么你必须要实现这些接口。比如:
public class BadUseOfConstants implements BadIrrationalConstants {
    public static double sinPiOverFour() {
       return SQRT_TWO / 2;
     }}

EffectiveJava第19条对这种方式提出反对,理由如下

1.接口被用作一个类型,通过此类型可以引用这个类的实例,为了其他目的定义接口不合适。

2.类中使用常量,这是实现细节,实现常量接口后,把这个实现细节泄漏到该类的API中,对类的用户也没有价值

3.将来类不需要这些常量了,仍必须实现这个接口,以保证兼容性。

4.一个非final类实现一个常量接口,它的所有子类的名字空间会被接口中的常量污染。

5.接口A中有个常量 接口B中也有个与A中名字一样值不一样的常量。类C 同时实现A B 接口的时候 ,要用这个常量就冲突了

第二种:使用枚举类定义常量,如下:

public enum Test {       //enum相当于class的位置,Test为类名
ONE, TWO, THREE   //枚举的常量名,使用时用Test.ONE表示
}

如果想使用枚举类中定义的常量,只需导入该枚举类,然后直接使用即可,如:

int i = Test.ONE;

枚举类一般是用来是作为一些属性相同或相近的常量,如颜色、年份等;不太适合几个常量之间没有太多相似度或关系的情形。

第三种:使用static import导入需要的常量

这种方式是在1.5之后才添加的。具体使用如下,例如我们在自己的类中要使用上文中定义的BadIrrationalConstants类:

import static com.shansun.staticex.IrrationalConstants. SQRT_TWO; 
……
public static double sinPiOverFour() {
       return SQRT_TWO / 2;
}

该方法适合当需要从别的类引入少数几个静态常量的时候,但不宜频繁使用该方法,比如一下子引入了多个常量,这样会影响到了程序的可读性了。

第四种:使用不可实例化的辅助类存放常量

获取这种常量定义方式是大家最常见到也最常用的一种方式了。定义方法如下:

public class Constants{
private Constants(){}
public static final double PI=3.14;
}

我们一般见到比较多的就是这种用法了,Constants.PI——是不是很眼熟呢?

<!--EndFragment--> p>