轉自:初始化有序常量的一點小技巧
編寫程式有時會用到有序常量。一個常見的情況是對命令列參數進行處理,如下的程式碼片段:
public class A { ……. privatestatic final int PARAM_1 = 0; privatestatic final int PARAM_2 = 1; privatestatic final int PARAM_3 = 2; privatestatic final int PARAM_4 = 3; privatestatic final int PARAMS_COUNT = 4; ……. publicstatic void main(String[] args) { if(args.length != PARAMS_COUNT) { System.out.println("Usage:program <Param_1> <Param_2> <Param_3> <Param_3><Param_4>"); System.exit(1); } callFun1(args[PARAM_1],args[PARAM_2]); callFun2(args[PARAM_1],args[PARAM_3], args[PARAM_4]); }}
PARAM_1到PARAM_4就是我這裡說的有序產量,這樣的常量通常被賦予一段順序的值。但如果像上面這段代碼的寫法,將會在程式維護時帶來一些小麻煩。比如增加一個新的產量PARAM_5,除了需要定義型的常量以外,還需要調整PARAMS_COUNT的值。如果需要在原序列中插入一個新的常量,那就更麻煩了,不僅需要調整PARAMS_COUNT的值,還需要調整插入位置之後的常量的值。如在上面的代碼中插入一個常量PARAM_NEW到PARAM_3的位置:
…….
privatestatic final int PARAM_1 = 0; privatestatic final int PARAM_2 = 1; privatestatic final int PARAM_NEW = 2 // New Constant privatestatic final int PARAM_3 = 3; // Need Changed privatestatic final int PARAM_4 = 4; // Need Changed privatestatic final int PARAMS_COUNT = 5; // NeedChanged
…….
其實我們只需要引入一個靜態變數就可以比較好的解決這個問題。下面是修改後的代碼:
public class A { ……. privatestatic int PARAM_INDEX = 0; privatestatic final int PARAM_1 = PARAM_INDEX++; privatestatic final int PARAM_2 = PARAM_INDEX++; privatestatic final int PARAM_3 = PARAM_INDEX++; privatestatic final int PARAM_4 = PARAM_INDEX++; privatestatic final int PARAMS_COUNT = PARAM_INDEX; ……. }
在新的代碼中,我們引入了一個變數PARAM_INDEX,並賦予一個初始值(這裡是零),藉助於對這個變數,我們消除了寫入程式碼常量的值帶來的那些弊端。同樣插入一個新的常量,現在我們只需要增加新的內容,而不需要改變原有的代碼了。代碼如下:
public class A { ……. privatestatic int PARAM_INDEX = 0; privatestatic final int PARAM_1 = PARAM_INDEX++; privatestatic final int PARAM_2 = PARAM_INDEX++; privatestatic final int PARAM_NEW = PARAM_INDEX++; // New Constant privatestatic final int PARAM_3 = PARAM_INDEX++; privatestatic final int PARAM_4 = PARAM_INDEX++; privatestatic final int PARAMS_COUNT = PARAM_INDEX; ……. }
PS:使用的時候發現了個小缺陷:在switch裡使用這些常量會報錯“case expressions must be constant expressions”,但是用在if裡沒事。本來是想用這種方法代替C++中的enum用法的,java的enum太費事。