IllegalStateException 是主动抛出的状态违规信号,核心在于方法入口前用明确状态字段校验(如枚举),禁止外部试探、封装校验逻辑,异常消息需含实际状态、期望状态和方法名,并保障线程安全与日志追溯。

IllegalStateException 本身不用于“判定”生命周期状态,而是你主动抛出的信号——它告诉你:对象当前状态不允许执行这个操作。真正起作用的是抛出异常前的那行状态检查逻辑。
在方法入口显式校验状态
不要等异常发生才反应,而要在关键操作开始前,用清晰的状态字段(如枚举或布尔值)做判断:
- 调用 start() 前,检查是否为
CREATED或STOPPED;若已是STARTED,立即抛出IllegalStateException("already started") - 调用 processData() 前,确认状态 !=
DESTROYED;否则抛"object is no longer usable" - 避免用
try-catch包裹可能抛出该异常的方法来“试探”状态——这不是检测手段,是设计缺陷
封装校验逻辑,不暴露状态访问器
别提供 getState() 或 isStarted() 这类公有方法让外部自行判断。把状态约束内聚进每个可变方法里:
- 比如
write(byte[])内部直接检查if (state != OPEN && state != FLUSHED) - 这样调用方无需关心状态细节,也杜绝了“检查完状态、执行前被并发修改”的竞态风险
异常消息要带上下文,方便定位
抛出时别只写“Operation not allowed”。消息必须包含三要素:
立即学习“Java免费学习笔记(深入)”;
- 当前实际状态(如
CLOSED) - 期望的合法状态(如
OPEN或FLUSHED) - 被调用的方法名(如
write())
✅ 推荐写法:new IllegalStateException("Cannot call write() in state CLOSED; expected OPEN or FLUSHED")
配合线程安全与日志辅助排查
多线程下状态易被干扰,需同步保障校验与执行的原子性:
- 简单状态用
volatile,复合状态优先用AtomicReference<State> - 在抛异常前加一条
DEBUG日志,记录对象 ID、线程名、时间戳,便于追溯并发错乱场景


















