java.lang.IllegalStateException
java.lang.IllegalStateException
DodaTech
3 min read
IllegalStateException signals a method was called when the object was in the wrong state. The arguments are valid but the object’s lifecycle forbids the operation.
What It Means
Think of an object as having a lifecycle — it goes through different states. Some operations are only valid in certain states. For example, calling next() on an iterator that has no more elements, or starting a thread that’s already running.
Why It Happens
- You call
iterator.next()without checkingiterator.hasNext(). - You call
start()on a thread that’s already running. - You try to commit a transaction that’s already committed or rolled back.
- You call methods on a closed
Connection,Stream, orSocket. - You try to modify an immutable object after creation.
- You call
add()on a fixed-size collection likeArrays.asList().
How to Fix It
1. Always check state before calling state-dependent methods
List<String> names = List.of("Alice", "Bob");
Iterator<String> it = names.iterator();
// BUG: no check before next()
while (true) {
System.out.println(it.next()); // throws when exhausted
}
// FIX: check hasNext()
while (it.hasNext()) {
System.out.println(it.next()); // safe
}2. Don’t restart threads
Thread t = new Thread(() -> System.out.println("Working..."));
t.start();
t.start(); // throws IllegalThreadStateException3. Check if a resource is closed before using it
public class DatabaseConnection {
private boolean closed = false;
public void query(String sql) {
if (closed) {
throw new IllegalStateException("Connection is already closed");
}
// execute query
}
public void close() {
this.closed = true;
}
}
// Proper usage
DatabaseConnection conn = new DatabaseConnection();
conn.query("SELECT 1");
conn.close();
conn.query("SELECT 2"); // throws IllegalStateException4. Use the Builder pattern to avoid incomplete objects
public class HttpClient {
private final String baseUrl;
private final int timeout;
private HttpClient(Builder builder) {
if (builder.baseUrl == null || builder.baseUrl.isBlank()) {
throw new IllegalStateException("baseUrl is required");
}
this.baseUrl = builder.baseUrl;
this.timeout = builder.timeout;
}
public static class Builder {
private String baseUrl;
private int timeout = 5000;
public Builder baseUrl(String url) {
this.baseUrl = url;
return this;
}
public HttpClient build() {
return new HttpClient(this);
}
}
}
// Usage — can't forget required fields
HttpClient client = new HttpClient.Builder()
.baseUrl("https://api.example.com")
.timeout(10000)
.build();5. Use Optional to represent state presence
// Instead of returning null when no data is available
public Optional<String> getConfigValue(String key) {
return Optional.ofNullable(configMap.get(key));
}
// Caller checks state before consuming
Optional<String> value = getConfigValue("timeout");
if (value.isPresent()) {
process(value.get()); // safe
} Previous
fatal: unable to access '...': Could not resolve host
Next
PermissionError: [Errno 13] Permission denied
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro