状态机中用位运算组合状态标志位,每个状态对应唯一2的幂次值,通过|组合、&检测、&~清除、^切换,实现高效、紧凑、常数时间的状态管理。

在状态机设计中,用位运算组合多个独立的状态标志位,核心是把每个状态当作一个二进制位(bit),利用 |(或)、&(与)、~(非)、^(异或)等操作高效地设置、检查、清除或翻转状态,避免使用多个布尔变量或枚举集合,节省内存且提升判断效率。
用 int 或 long 定义状态标志位
每个状态对应一个唯一的 2 的幂次值,确保各标志位互不重叠:
static final int STATE_IDLE = 1 << 0; // 1static final int STATE_RUNNING = 1 << 1; // 2static final int STATE_PAUSED = 1 << 2; // 4static final int STATE_ERROR = 1 << 3; // 8
这样任意组合(如 STATE_RUNNING | STATE_PAUSED)结果唯一,且每个 bit 位置独立可识别。
用按位或(|)组合多个状态
状态机可能同时处于多种“正交”状态(例如:既在运行,又处于低功耗模式),用 | 合并标志位:
立即学习“Java免费学习笔记(深入)”;
int currentState = STATE_RUNNING | STATE_LOW_POWER;- 等价于
2 | 16 = 18(二进制10010),第 1 位和第 4 位为 1
支持链式组合:STATE_RUNNING | STATE_PAUSED | STATE_DIRTY,语义清晰,无副作用。
用按位与(&)检测某个状态是否启用
判断当前是否包含某状态,只需与对应标志位做 &,结果非零即存在:
if ((currentState & STATE_RUNNING) != 0) { ... }-
if ((currentState & (STATE_PAUSED | STATE_IDLE)) != 0) { ... }—— 检查是否处于任一指定状态
注意不能写成 == STATE_PAUSED,因为 currentState 可能是多状态组合值。
用按位与非(& ~)清除特定状态
要退出某个状态但保留其余,用 & ~flag 清零对应位:
-
currentState = currentState & ~STATE_PAUSED;—— 关闭暂停态 -
currentState &= ~STATE_ERROR;—— 简洁写法,等效于上式
原理是 ~STATE_PAUSED 把暂停位设为 0、其余位全为 1,再与原值相与,仅该位被清零,其他不变。
用异或(^)切换状态(开/关)
适合需要翻转某个状态的场景(比如“点击切换静音”):
currentState ^= STATE_MUTED;- 若原值含
STATE_MUTED,异或后清除;不含则添加——无需先判断
这是位运算独有的简洁能力,比 if-else 切换更紧凑、线程安全(单条指令级原子性,但整变量读写仍需同步保障)。
本质上,位运算让状态机具备了“轻量级位图”的能力:一个整数承载多个布尔状态,操作常数时间、无对象开销、缓存友好。只要状态总数 ≤ 32(int)或 ≤ 64(long),就非常适用。


















