illegalstateexception 是开发者主动抛出的断言失败信号,用于在对象处于不允许执行某操作的状态时提示错误;它不提供状态查询能力,真正判定需在抛出前由代码显式检查状态字段或枚举,并封装在校验逻辑中。
illegalstateexception 本身不是用来“判定”生命周期状态的工具,而是当检测到对象处于**不允许执行某操作的状态**时,由开发者主动抛出的信号。它不提供查询能力,而是表达一种“断言失败”的结果。真正判定状态的逻辑,必须由你写在抛出异常之前。
明确状态边界,预先检查再操作
在执行关键流程前,用清晰的字段或枚举记录对象当前所处阶段(如 CREATED、STARTED、STOPPED、DESTROYED),并在方法入口处显式校验:
- 例如调用
start()前,检查是否为CREATED或STOPPED;若已是STARTED,就抛IllegalStateException("already started") - 调用
processData()前,确认状态不为DESTROYED,否则抛异常并说明“object is no longer usable” - 避免仅靠 try-catch 捕获 IllegalStateException 来“试探”状态——这属于反模式,掩盖了本该由逻辑控制的流程约束
把状态检查内聚在业务方法中,而非暴露状态访问器
不要提供类似 getState() 这样的公有方法让外部自行判断;而是将状态校验封装进每个可变操作里:
- 用户调用
save(),内部自动检查是否处于EDITABLE状态;不是?直接抛异常 - 这样既保证了安全性,又简化了调用方逻辑——他们只需关注“想做什么”,不用操心“能不能做”
- 如果多个方法共享同一状态约束,可提取为私有辅助方法,如
ensureEditable()
异常消息要具体,辅助定位问题根源
抛出 IllegalStateException 时,消息应包含:当前状态、期望状态、被调用的方法名:
- ✅ 推荐:
new IllegalStateException("Cannot call write() in state CLOSED; expected OPEN or FLUSHED") - ❌ 避免:
new IllegalStateException("Operation not allowed")—— 无法用于调试或日志分析 - 结合日志框架,在抛出前打一条 DEBUG 级别日志,记录上下文(如对象 ID、线程名),便于排查并发导致的状态错乱
配合不可变性与线程安全设计,减少误判风险
状态变更本身需受控,否则多线程下即使检查了状态,也可能在执行前被其他线程改掉:
- 对状态字段使用
volatile(简单状态)或AtomicInteger/AtomicReference(复合状态) - 更稳妥的做法是用同步块或
ReentrantLock保证“检查 + 执行”原子性,尤其涉及资源分配或状态跃迁时 - 考虑构建有限状态机(FSM)模型,用库如 Spring State Machine 管理合法转换,自动拦截非法调用并抛出 IllegalStateException










