java中用long类型位操作存储状态标志,核心是将布尔状态映射到64位的特定位,通过|、&、^等运算高效存取;需用static final long定义标志常量,操作long变量而非long对象,并在并发场景使用atomiclong保证线程安全。

Java 中用 Long 包装类(实际底层是 long 基本类型)做位操作存储状态标志,核心在于把每个布尔状态映射到 long 的某一位上,利用位运算高效存取。关键不是“用包装类操作”,而是借 Long 作为 64 位容器承载标志,同时兼顾可读性与线程安全(如需)。
用 long 原生位操作定义和设置状态标志
不要对 Long 对象本身做位运算(它不可变),而是操作其 long 值。推荐用 public static final long 定义清晰的标志位常量:
public static final long FLAG_READ = 1L // 第 0 位public static final long FLAG_WRITE = 1L // 第 1 位public static final long FLAG_ACTIVE = 1L // 第 2 位public static final long FLAG_LOCKED = 1L // 第 3 位
使用时直接对 long 变量操作:
- 设标志:
status |= FLAG_WRITE; - 清标志:
status &= ~FLAG_LOCKED; - 判断是否设置:
(status & FLAG_READ) != 0 - 切换标志:
status ^= FLAG_ACTIVE;
封装成工具类提升可维护性和类型安全
避免裸写 magic number,把标志集合封装为枚举或工具类。例如定义枚举并关联位值:
public enum StatusFlag {
READ(0), WRITE(1), ACTIVE(2), LOCKED(3);
private final long bit;
StatusFlag(int position) {
this.bit = 1L
<p>再提供静态工具方法:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java"><img
src="https://img.php.cn/upload/skill/000/000/081/178955835420587.jpg" alt="Alibabacloud Sdk Client Initialization For Java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="overflowclass">Alibabacloud Sdk Client Initialization For Java</a>
<p class="overflowclass">在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。</p>
</div>
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
public static long set(long status, StatusFlag flag) { return status | flag.value(); }public static long clear(long status, StatusFlag flag) { return status & ~flag.value(); }public static boolean isSet(long status, StatusFlag flag) { return (status & flag.value()) != 0; }
这样业务代码更清晰:status = StatusUtils.set(status, StatusFlag.WRITE);
注意 Long 包装类的不可变性与线程安全场景
Long 是不可变对象,不能直接修改其内部值。所以“存储”状态必须用可变容器承载 long 值:
- 普通场景:用
long局部变量或成员字段(如private long status;) - 并发场景:用
AtomicLong,它支持原子位操作:atomicStatus.accumulateAndGet(FLAG_WRITE, (prev, flag) -> prev | flag);或用updateAndGet配合 lambda - 避免误用:
Long l = 10L; l |= FLAG_WRITE;这行会自动拆箱→运算→装箱,产生新对象,原引用不变——本质是无效操作
解析多个标志时推荐用位掩码批量判断
当需要检查一组相关状态(比如“是否只读且活跃”),不要连写多个 & 判断,而应预定义组合掩码:
public static final long MASK_READONLY_ACTIVE = FLAG_READ | FLAG_ACTIVE;- 校验:
(status & MASK_READONLY_ACTIVE) == MASK_READONLY_ACTIVE(确保两位都置 1) - 或宽松匹配:
(status & MASK_READONLY_ACTIVE) != 0(只要其中任一置 1)
也可用 Long.bitCount(status) 快速统计已启用的标志数量,辅助状态聚合分析。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










