談談列舉的新用法——java
阿新 • • 發佈:2018-12-30
問題的由來
前段時間改遊戲buff功能,幹了一件愚蠢的事情,那就是把列舉和運算集合在一起,然後執行一段時間後buff就出現各種問題,我當時懵逼了!
事情是這樣的,做過遊戲的都知道,buff,需要分型別,且包含是否需要切換場景刪除,下線刪除,死亡刪除等資訊,好吧我就把這個做到一起了用一個欄位標識!
問題就出來了;
/** * * <br> * author 失足程式設計師<br> * mail [email protected]<br> * phone 13882122019<br> */ public classEnumTest { private static final Logger log = Logger.getLogger(EnumTest.class); public enum BuffType { Null(0, "空buff"), DieDel(62, "死亡刪除"), ChangeMapDel(63, "切換場景刪除"); int index; long value; String msgString; BuffType(int index, String msg) { this.index = index; this.value = 1L << index; msgString = msg; } public int getIndex() { return index; } public String getMsgString() { return msgString; }public static BuffType getBuffType(int index) { BuffType[] values = BuffType.values(); for (BuffType buffType : values) { if (buffType.getIndex() == index) { return buffType; } } return null; } /** * 是否包含一個狀態 * * @param tvalue * @return */ public boolean hasFlag(BuffType tvalue) { return (value & tvalue.value) != 0; } /** * 增加一個狀態 * * @param buffType */ public void addStatus(BuffType buffType) { value = value | buffType.value; } /** * 移除一個狀態 * * @param buffType */ public void removeStatus(BuffType buffType) { value = value & (~buffType.value); } } public static void main(String[] args) { BuffType buffType = BuffType.Null; buffType.addStatus(BuffType.DieDel); } }
晃眼一看好像沒什麼問題對吧??當然你已經有過這樣一次上當經歷的寧說!
解密
當時情況是這樣的,我修改完buff功能模組以後我就讓策劃測試程式碼功能,我繼續改其他功能模組,然後策劃告訴我不對,
我準備除錯的時候可是程式碼已經不是原始碼了,需要重新啟動程式才能除錯,
好吧我重啟完成,測試告訴我對了,好吧我又繼續該功能模組,過了半小時策劃再次告訴我不對了,我又一次的需要重啟才能除錯,
好吧就這樣陷入死迴圈,一直到晚上吃飯我。、我直接說改了一下午程式碼走出去活動活動吃飯回來繼續看,
回來後我就不再修改程式碼,就等測試這個功能;這下發現了情況,
使用流程
public static void main(String[] args) { BuffType buffType = BuffType.Null; buffType.addStatus(BuffType.DieDel); if (buffType.hasFlag(BuffType.DieDel)) { System.out.println("下線需要刪除buff"); } buffType = BuffType.Null; if (buffType.hasFlag(BuffType.DieDel)) { System.out.println("下線需要刪除buff"); } }
接下來看看輸出結果:
問題來了為什麼我明明是新來的一個賦值物件為啥還是包含狀態???
我想了一下,突然回過神來,列舉是靜態常量啊,我的任何修改都會導致所有引用全部修改,
好吧,既然找到問題了就來修改吧。
再次闡述一下,我這裡需要列舉的原因,一個是為了策劃配置方便,他們只要1,2,3這種形式
而我需要位移運算,儲存狀態值,並且還需要列舉型別的文字描述,提供給運維,運營和策劃看的。
修改後如何使用
因為我個人喜歡比較喜歡列舉,加上能定義列舉的方便些;
接下來就修改,修改,
1 /** 2 * 3 * <br> 4 * author 失足程式設計師<br> 5 * mail [email protected]<br> 6 * phone 13882122019<br> 7 */ 8 public class EnumTest { 9 10 private static final Logger log = Logger.getLogger(EnumTest.class); 11 12 private long tVlaue = 0; 13 14 public enum BuffType { 15 16 DieDel(62, "死亡刪除"), 17 ChangeMapDel(63, "切換場景刪除"); 18 19 int index; 20 long value; 21 String msgString; 22 23 BuffType(int index, String msg) { 24 this.index = index; 25 this.value = 1L << index; 26 msgString = msg; 27 } 28 29 public int getIndex() { 30 return index; 31 } 32 33 public String getMsgString() { 34 return msgString; 35 } 36 } 37 38 /** 39 * 根據策劃配置還原列舉 40 * 41 * @param index 42 * @return 43 */ 44 public static BuffType getBuffType(int index) { 45 BuffType[] values = BuffType.values(); 46 for (BuffType buffType : values) { 47 if (buffType.getIndex() == index) { 48 return buffType; 49 } 50 } 51 return null; 52 } 53 54 /** 55 * 是否包含一個狀態 56 * 57 * @param tvalue 58 * @return 59 */ 60 public boolean hasFlag(BuffType tvalue) { 61 return (tVlaue & tvalue.value) != 0; 62 } 63 64 /** 65 * 增加一個狀態 66 * 67 * @param buffType 68 */ 69 public void addStatus(BuffType buffType) { 70 tVlaue = tVlaue | buffType.value; 71 } 72 73 /** 74 * 移除一個狀態 75 * 76 * @param buffType 77 */ 78 public void removeStatus(BuffType buffType) { 79 tVlaue = tVlaue & (~buffType.value); 80 } 81 82 public static void main(String[] args) { 83 EnumTest buffType = new EnumTest(); 84 85 buffType.addStatus(BuffType.DieDel); 86 if (buffType.hasFlag(BuffType.DieDel)) { 87 System.out.println("包含:" + BuffType.DieDel.getMsgString()); 88 } else { 89 System.out.println("不包含:" + BuffType.DieDel.getMsgString()); 90 } 91 92 buffType = new EnumTest(); 93 94 if (buffType.hasFlag(BuffType.DieDel)) { 95 System.out.println("包含:" + BuffType.DieDel.getMsgString()); 96 } else { 97 System.out.println("不包含:" + BuffType.DieDel.getMsgString()); 98 } 99 } 100 }
結果:
我知道這篇文字對大神沒什麼用,希望對新手有所幫助,同時也記錄一次犯二的我!