zoukankan      html  css  js  c++  java
  • 谈谈枚举的新用法——java

    问题的由来

    前段时间改游戏buff功能,干了一件愚蠢的事情,那就是把枚举和运算集合在一起,然后运行一段时间后buff就出现各种问题,我当时懵逼了!

    事情是这样的,做过游戏的都知道,buff,需要分类型,且包含是否需要切换场景删除,下线删除,死亡删除等信息,好吧我就把这个做到一起了用一个字段标识!

    问题就出来了;

    /**
     *
     * <br>
     * author 失足程序员<br>
     * mail 492794628@qq.com<br>
     * phone 13882122019<br>
     */
    public class EnumTest {
    
        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 492794628@qq.com<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 }

    结果:

    我知道这篇文字对大神没什么用,希望对新手有所帮助,同时也记录一次犯二的我!

  • 相关阅读:
    Windows Server 2008 R2域控组策略设置禁用USB
    Windows Server 2008 R2组策略设置计算机配置和用户配置
    Windows Server 2008 R2父域管理员与子域管理员相互登录访问
    转载:如何处理浏览器的断网情况?
    转载:浏览器缓存库设计总结(localStorage/indexedDB)
    手写启动一个本地服务器的命令行工具
    Node.js-核心模块-zlib
    使用console.log打印公司招聘信息和字符画
    转载:准备刷 leetcode 了,才发现自己连时间复杂度都不懂
    转载:前端通信那些事儿
  • 原文地址:https://www.cnblogs.com/shizuchengxuyuan/p/5647081.html
Copyright © 2011-2022 走看看