问题的由来

前段时间改游戏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这种形式

而我需要位移运算,保存状态值,并且还需要枚举类型的文字描述,提供给运维,运营和策划看的。

修改后如何使用

因为我个人喜欢比较喜欢枚举,加上能定义枚举的方便些;

接下来就修改,修改,

 /**
  *
  * <br>
  * author 失足程序员<br>
  * mail 492794628@qq.com<br>
  * phone 13882122019<br>
  */
 public class EnumTest {

     private static final Logger log = Logger.getLogger(EnumTest.class);

     private long tVlaue = 0;

     public enum BuffType {

         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;
         }
     }

     /**
      * 根据策划配置还原枚举
      *
      * @param index
      * @return
      */
     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 (tVlaue & tvalue.value) != 0;
     }

     /**
      * 增加一个状态
      *
      * @param buffType
      */
     public void addStatus(BuffType buffType) {
         tVlaue = tVlaue | buffType.value;
     }

     /**
      * 移除一个状态
      *
      * @param buffType
      */
     public void removeStatus(BuffType buffType) {
         tVlaue = tVlaue & (~buffType.value);
     }

     public static void main(String[] args) {
         EnumTest buffType = new EnumTest();

         buffType.addStatus(BuffType.DieDel);
         if (buffType.hasFlag(BuffType.DieDel)) {
             System.out.println("包含:" + BuffType.DieDel.getMsgString());
         } else {
             System.out.println("不包含:" + BuffType.DieDel.getMsgString());
         }

         buffType = new EnumTest();

         if (buffType.hasFlag(BuffType.DieDel)) {
             System.out.println("包含:" + BuffType.DieDel.getMsgString());
         } else {
             System.out.println("不包含:" + BuffType.DieDel.getMsgString());
         }
     }
 }

结果:

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

谈谈枚举的新用法——java的更多相关文章

  1. K:java中枚举的常见用法

    用法一:常量   在JDK1.5 之前,我们定义常量都是: public static fianl.....现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. ...

  2. Java枚举类型的用法

    JDK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 1.用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fia ...

  3. Java中枚举的常见用法

    在JDK1.5以后引入了一种新的类型,就是枚举(enum).enum是用来声明枚举类型数据,它可以像数组一样存储许多的元素,但是不同于数组的是,它除了数字不能存储以外, 其他类型的如字母.特殊符号.汉 ...

  4. Java SE 枚举的基本用法

    出于对自己基础的稳打,期末考试后依旧对SE部分进行复习 枚举的基本用法 public enum Season { SPRING,SUMMER,AUTUMN,WINTER } public class ...

  5. C++11之for循环的新用法《转》

    相关资料:https://legacy.gitbook.com/book/changkun/cpp1x-tutorial/details C++11之for循环的新用法 C++使用如下方法遍历一个容器 ...

  6. OpenJDK源码研究笔记(十):枚举的高级用法,枚举实现接口,竟是别有洞天

    在研究OpenJDK,Java编译器javac源码的过程中,发现以下代码. 顿时发现枚举类竟然也有如此"高端大气上档次"的用法. 沙场点兵(用法源码) com.sun.tools. ...

  7. 详解Vue的slot新用法

    摘要: 理解Vue插槽. 作者:前端小智 原文:vue 2.6 中 slot 的新用法 Fundebug经授权转载,版权归原作者所有. 为了保证的可读性,本文采用意译而非直译. 最近发布不久的Vue ...

  8. JOptionPane用法--java

    JOptionPane用法--java JOptionPane的简单应用: 1.首先引入包: import javax.swing.JOptionPane; 2.添加如下代码: Object[] op ...

  9. C++虚函数的新用法

    1.今天在segmentfault上看到了一个C++虚函数的新用法,先上代码 #include <iostream> using namespace std; class B { publ ...

随机推荐

  1. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  2. html与html5

    HTML 是一种在 Web 上使用的通用标记语言.HTML 允许你格式化文本,添加图片,创建链接.输入表单.框架和表格等等,并可将之存为文本文件,浏览器即可读取和显示.HTML 的关键是标签,其作用是 ...

  3. Ubuntu 16.10 安装byzanz截取动态效果图工具

    1.了解byzanz截取动态效果图工具 byzanz能制作文件小,清晰的GIF动态效果图,不足就是,目前只能通过输入命令方式来录制. byzanz主要的参数选项有: -d, --duration=SE ...

  4. 如何将VCSA添加到微软域控环境,并且实现微软域账号登陆vCenter

    v:* { } o:* { } w:* { } .shape { } p.msonormal,li.msonormal,div.msonormal { margin: 0cm; margin-bott ...

  5. Node.js入门(一)

    一.Node.js本质上是js的运行环境. 二.可以解析js代码(没有浏览器安全级的限制): 提供系统级的API:1.文件的读写 2.进程的管理 3.网络通信 三.可以关注的四个网站: 1.https ...

  6. 解决:SharePoint当中的STP网站列表模板没有办法导出到其它语言环境中使用

    首在在你的英文版本上,导出列表或是网站的模板,这个文件可能是这样滴:template.stp 把这个文件 template.stp 命名为 template.cab 解压 这个 *.cab 文件 在解 ...

  7. git快速get

    配置:git config --global user.name 'yangshaoxiang' git config --global user.email '254135495@qq.com' s ...

  8. ubuntu14.04redis安装以及扩展

    redis 安装http://my.oschina.net/quanpower/blog/282546#OSC_h2_2redis扩展安装wget https://github.com/nicolas ...

  9. WebAPI 2参数绑定方法

    简单类型参数 Example 1: Sending a simple parameter in the Url [RoutePrefix("api/values")] public ...

  10. Spring mvc @initBinder 类型转化器的使用

    一.单日期格式 因为是用注解完完成的后台访问,所以必须在大配置中配置包扫描器: 1.applicactionContext.xml <?xml version="1.0" e ...