谈谈枚举的新用法——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这种形式
而我需要位移运算,保存状态值,并且还需要枚举类型的文字描述,提供给运维,运营和策划看的。
修改后如何使用
因为我个人喜欢比较喜欢枚举,加上能定义枚举的方便些;
接下来就修改,修改,
/**
*
* <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的更多相关文章
- K:java中枚举的常见用法
用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.....现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. ...
- Java枚举类型的用法
JDK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 1.用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fia ...
- Java中枚举的常见用法
在JDK1.5以后引入了一种新的类型,就是枚举(enum).enum是用来声明枚举类型数据,它可以像数组一样存储许多的元素,但是不同于数组的是,它除了数字不能存储以外, 其他类型的如字母.特殊符号.汉 ...
- Java SE 枚举的基本用法
出于对自己基础的稳打,期末考试后依旧对SE部分进行复习 枚举的基本用法 public enum Season { SPRING,SUMMER,AUTUMN,WINTER } public class ...
- C++11之for循环的新用法《转》
相关资料:https://legacy.gitbook.com/book/changkun/cpp1x-tutorial/details C++11之for循环的新用法 C++使用如下方法遍历一个容器 ...
- OpenJDK源码研究笔记(十):枚举的高级用法,枚举实现接口,竟是别有洞天
在研究OpenJDK,Java编译器javac源码的过程中,发现以下代码. 顿时发现枚举类竟然也有如此"高端大气上档次"的用法. 沙场点兵(用法源码) com.sun.tools. ...
- 详解Vue的slot新用法
摘要: 理解Vue插槽. 作者:前端小智 原文:vue 2.6 中 slot 的新用法 Fundebug经授权转载,版权归原作者所有. 为了保证的可读性,本文采用意译而非直译. 最近发布不久的Vue ...
- JOptionPane用法--java
JOptionPane用法--java JOptionPane的简单应用: 1.首先引入包: import javax.swing.JOptionPane; 2.添加如下代码: Object[] op ...
- C++虚函数的新用法
1.今天在segmentfault上看到了一个C++虚函数的新用法,先上代码 #include <iostream> using namespace std; class B { publ ...
随机推荐
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(66)-MVC WebApi 用户验证 (2)
系列目录 前言: 回顾上一节,我们利用webapi简单的登录并进行了同域访问与跨域访问来获得Token,您可以跳转到上一节下载代码来一起动手. 继续上一篇的文章,我们接下来演示利用拿到的Token来访 ...
- WebSocket - ( 一.概述 )
说到 WebSocket,不得不提 HTML5,作为近年来Web技术领域最大的改进与变化,包含CSS3.离线与存储.多媒体.连接性( Connectivity )等一系列领域,而即将介绍的 WebSo ...
- MySQL优化聊两句
原文地址:http://www.cnblogs.com/verrion/p/mysql_optimised.html MySQL优化聊两句 MySQL不多介绍,今天聊两句该如何优化以及从哪些方面入手, ...
- Struts2入门(五)——OGNL和标签库
一.前言 OGNL和标签库的作用,粗暴一点说,就是减少在JSP页面中出现java代码,利于维护. 1.1.OGNL 1.1.1.什么是OGNL? OGNL(Object-Graph Navigatio ...
- SEED实验系列文章目录
美国雪城大学SEEDLabs实验列表 SEEDLabs是一套完整的信息安全实验,涵盖本科信息安全教学中的大部分基本原理.项目组2002年由杜文亮教授创建,目前开发了30个实验,几百所大学已采用.实验楼 ...
- oracle常用函数及示例
学习oracle也有一段时间了,发现oracle中的函数好多,对于做后台的程序猿来说,大把大把的时间还要学习很多其他的新东西,再把这些函数也都记住是不太现实的,所以总结了一下oracle中的一些常用函 ...
- mysql数据库主从同步
环境: Mater: CentOS7.1 5.5.52-MariaDB 192.168.108.133 Slave: CentOS7.1 5.5.52-MariaDB 192.168. ...
- 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法
转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...
- [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别
1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...
- Linux学习日记-EF6的安装升级(三)
在vs2013中使用EF是5的但是如果想使用 “来自数据库据的Code First” 这个生成模板就会发现 它会提示你EF的版本太低请升级 下面就是解决办法: 安装实体框架6 在工具菜单中,点击NuG ...