java枚举类本身不支持位运算,但可通过为每个枚举常量赋予2的幂值(如1、2、4、8),结合int/long位掩码模拟位标志行为,实现权限的组合、判断、增删;需注意32/64上限、序列化风险及非法值校验。

Java 枚举类本身不直接支持位运算(如 &、|、^、~),但可以通过为每个枚举常量赋予唯一的 2 的幂值(如 1, 2, 4, 8…),再配合 int 或 long 类型的位掩码(bitmask)来模拟“位标志”行为,从而高效组合、判断、增删权限。
给枚举赋 2 的幂值作为位标识
核心是让每个权限对应一个独立的二进制位。例如:
public enum Permission {
READ(1), // 0b0001
WRITE(2), // 0b0010
DELETE(4), // 0b0100
EXECUTE(8); // 0b1000
private final int value;
Permission(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
这样每个权限在整数中只占一位,互不干扰,可安全进行位运算。
用 int/long 存储组合权限(Bitmask)
不把多个枚举实例存成集合,而是用一个整数变量保存所有启用的权限位:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
组合权限:用
|(或)叠加多个权限 ——int perms = READ.getValue() | WRITE.getValue();→ 值为3(0b0011) -
检查权限:用
&(与)判断是否包含某权限 ——(perms & DELETE.getValue()) != 0 -
添加权限:用
|=——perms |= EXECUTE.getValue(); -
移除权限:用
& ~——perms &= ~WRITE.getValue(); -
切换权限:用
^(异或)——perms ^= DELETE.getValue();
封装工具方法提升可读性与安全性
避免裸写位运算,提供语义化操作:
public class PermissionSet {
private int bitmask;
public PermissionSet() {
this.bitmask = 0;
}
public PermissionSet add(Permission p) {
bitmask |= p.getValue();
return this;
}
public PermissionSet remove(Permission p) {
bitmask &= ~p.getValue();
return this;
}
public boolean has(Permission p) {
return (bitmask & p.getValue()) != 0;
}
public boolean hasAll(Permission... ps) {
int required = 0;
for (Permission p : ps) required |= p.getValue();
return (bitmask & required) == required;
}
public int getBitmask() {
return bitmask;
}
}
使用示例:new PermissionSet().add(READ).add(WRITE).has(DELETE) 返回 false。
注意边界与扩展性限制
位标志适合权限种类少、变动不频繁的场景:
-
上限明确:
int最多支持 32 种权限,long支持 64 种;超出需改用EnumSet或BitSet - 不可序列化枚举引用:存储的是整数,不是枚举实例本身;反序列化时需确保枚举定义未变更(否则位含义错乱)
-
无内置校验:若手动传入非法值(如
5),不会报错,但逻辑可能异常;建议构造时校验或用EnumSet辅助校验
若权限动态增减或数量超 64,优先考虑 EnumSet<permission></permission>(底层也是位向量,且类型安全)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










