illegalstateexception 表示对象当前状态不支持该操作,如线程重复启动、ui非主线程更新、容器未刷新时获取bean等;需在方法入口校验状态并给出具体错误信息。

IllegalStateException 是什么状态?
它不是空指针、不是数组越界,而是“对象当前根本没准备好干这事”。比如你调用 Iterator.next() 却没先调用 hasNext(),或者对已关闭的 HttpClient 发起请求——JVM 不拦你语法,但运行时直接抛这个异常。
关键在“状态”二字:它依赖对象内部某个布尔标记(如 closed、started、initialized)或阶段变量(如 state == State.READY),一旦条件不满足就炸。
哪些场景最容易触发 IllegalStateException?
-
Thread.start() 被重复调用(线程只能启动一次)
- Android 中在非主线程更新 UI(
View.post() 之外直接调 setText())
- Spring 的
ApplicationContext.getBean() 在容器未刷新(refresh())前调用
- Java NIO 的
ByteBuffer.flip() 后再写入,或 compact() 前没调 flip()
怎么写才不容易抛 IllegalStateException?
Thread.start() 被重复调用(线程只能启动一次)View.post() 之外直接调 setText())ApplicationContext.getBean() 在容器未刷新(refresh())前调用ByteBuffer.flip() 后再写入,或 compact() 前没调 flip()
核心是「检查状态,早抛早好」。别等用户调了 doSomething() 才在方法末尾查 if (!ready) throw new IllegalStateException()——应该在入口处立刻验。
示例:
立即学习“Java免费学习笔记(深入)”;
public void sendRequest() {
if (closed) {
throw new IllegalStateException("Connection is closed");
}
if (state != State.CONNECTED) {
throw new IllegalStateException("Connection not established: " + state);
}
// ... real logic
}注意两点:
- 错误信息里带具体状态(state 值),别只写“not ready”
- 检查顺序要合理:先判是否已销毁(closed),再判是否就绪(CONNECTED),避免空指针或逻辑错乱
和 IllegalArgumentException、UnsupportedOperationException 怎么分?
三者常被混用,但语义不同:
-
IllegalArgumentException:参数本身不对,比如传null给不允许为空的字段 -
IllegalStateException:参数没问题,但对象当前状态不允许这次调用 -
UnsupportedOperationException:这方法压根就不该被实现(如不可变集合的add())
比如 ArrayList.add() 在并发修改时抛 ConcurrentModificationException(继承自 RuntimeException,但语义更专),而你自己写的连接池如果在 shutdown() 后还允许 acquire(),那就该抛 IllegalStateException——因为不是参数错,也不是功能不支持,是“此刻不能做”。
状态校验容易漏掉边界:比如多线程下检查完 !closed 瞬间就被其他线程关了,所以真正关键操作前还得加同步或用原子状态机。这点很多人忽略,直到压测崩了才回头补锁。










