Definition
- IllegalArgumentException (IAE) = the caller passed a bad argument. Any valid argument would work if the caller provided one. Examples: null, negative amount, blank ID.
- IllegalStateException (ISE) = the object is in the wrong state for this operation. The arguments are fine, but the object cannot handle the request right now. Examples: connection closed, iterator consumed, trade already settled.
- Decision test: would this method work with different arguments? Yes = ISE (state problem). No = IAE (input problem).
- Objects.requireNonNull() throws NPE for null args (JDK convention). Guava's
checkArgument()throws IAE,checkState()throws ISE.
IAE is Priya writing a negative amount on the withdrawal form at National Bank of India. The form is wrong. Fix it and try again. ISE is Priya arriving at the counter after closing time. Her form is perfect, but the counter cannot serve her right now. IAE = bad input. ISE = bad timing.
Understanding the Concepts
When do you throw IllegalArgumentException?
Throw IAE when the method's arguments are invalid. The caller can fix this by passing valid input.
package com.bank.service;
import java.math.BigDecimal;
import java.util.Objects;
public class IAEDemo {
public static void withdraw(String accountId, BigDecimal amount) {
if (accountId == null || accountId.isBlank()) {
throw new IllegalArgumentException("accountId must not be blank");
}
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("amount must be positive: " + amount);
}
System.out.println("Withdrawn Rs." + amount + " from " + accountId);
}
public static void main(String[] args) {
withdraw("SAV2001", new BigDecimal("5000"));
try {
withdraw("SAV2001", new BigDecimal("-100"));
} catch (IllegalArgumentException e) {
System.out.println("IAE: " + e.getMessage());
}
}
}
Withdrawn Rs.5000 from SAV2001
IAE: amount must be positive: -100
When do you throw IllegalStateException?
Throw ISE when the object is in the wrong state for the requested operation.
package com.bank.service;
public class ISEDemo {
static class TradingSession {
private boolean open = false;
void open() { open = true; System.out.println("Session opened"); }
void close() { open = false; System.out.println("Session closed"); }
void executeTrade(String tradeId) {
if (!open) {
throw new IllegalStateException("Trading session is closed. Call open() first.");
}
System.out.println("Executed: " + tradeId);
}
}
public static void main(String[] args) {
TradingSession session = new TradingSession();
try {
session.executeTrade("TRD-001"); // ISE: session not open
} catch (IllegalStateException e) {
System.out.println("ISE: " + e.getMessage());
}
session.open();
session.executeTrade("TRD-001"); // works after open()
}
}
ISE: Trading session is closed. Call open() first.
Session opened
Executed: TRD-001
How does Objects.requireNonNull work?
It is the JDK standard for null argument validation. It throws NullPointerException, not IAE, following the convention that null where non-null is required is signaled by NPE.
package com.bank.demo;
import java.math.BigDecimal;
import java.util.Objects;
public class RequireNonNullDemo {
public static void transfer(String from, String to, BigDecimal amount) {
Objects.requireNonNull(from, "from account must not be null");
Objects.requireNonNull(to, "to account must not be null");
Objects.requireNonNull(amount, "amount must not be null");
System.out.println("Transfer Rs." + amount + " from " + from + " to " + to);
}
public static void main(String[] args) {
transfer("SAV2001", "CUR3001", new BigDecimal("10000"));
try {
transfer(null, "CUR3001", new BigDecimal("10000"));
} catch (NullPointerException e) {
System.out.println("NPE: " + e.getMessage());
}
}
}
Transfer Rs.10000 from SAV2001 to CUR3001
NPE: from account must not be null
What is the decision guide?
Ask: would this method work if the caller passed DIFFERENT arguments?
package com.bank.demo;
public class DecisionGuideDemo {
public static void main(String[] args) {
System.out.println("Decision guide:");
System.out.println();
System.out.println("Q: Would different arguments fix the problem?");
System.out.println(" YES → IllegalStateException (state is wrong)");
System.out.println(" NO → IllegalArgumentException (input is wrong)");
System.out.println();
System.out.println("Q: Is the problem WHAT was passed or WHEN it was called?");
System.out.println(" WHAT → IAE");
System.out.println(" WHEN → ISE");
System.out.println();
System.out.println("HTTP mapping:");
System.out.println(" IAE → 400 Bad Request (client fix: send valid data)");
System.out.println(" ISE → 409 Conflict or 503 (server state problem)");
}
}
Decision guide: Q: Would different arguments fix the problem? YES → IllegalStateException (state is wrong) NO → IllegalArgumentException (input is wrong) Q: Is the problem WHAT was passed or WHEN it was called? WHAT → IAE WHEN → ISE HTTP mapping: IAE → 400 Bad Request (client fix: send valid data) ISE → 409 Conflict or 503 (server state problem)
What should a senior engineer know?
- NPE vs IAE for null. Joshua Bloch (Effective Java) recommends NPE for null arguments. Objects.requireNonNull follows this convention. Some teams prefer IAE for null. Be consistent.
- Guava Preconditions.
checkArgument(condition, "msg")throws IAE.checkState(condition, "msg")throws ISE. More concise than manual if-throw.
What are common interview follow-up questions?
- Does Objects.requireNonNull throw NPE or IAE? (NPE by design.)
- When is ISE appropriate? (Object in wrong state: closed, consumed, already initialized.)
- What HTTP status maps to IAE vs ISE? (IAE = 400, ISE = 409 or 503.)
Visual Overview
Input validation: State validation: ┌──────────────────────┐ ┌──────────────────────┐ │ throw IAE │ │ throw ISE │ │ "amount is negative" │ │ "session is closed" │ │ Caller's fault │ │ Wrong timing │ │ Fix: send valid data │ │ Fix: call open() first│ │ HTTP 400 │ │ HTTP 409 / 503 │ └──────────────────────┘ └──────────────────────┘ Decision: different args fix it? YES → ISE NO → IAE
Key Takeaway
IllegalArgumentException means the caller passed invalid input: null, negative, wrong format. The fix is to provide valid arguments. IllegalStateException means the object is in the wrong state for the operation: connection closed, session not started, iterator consumed. The fix is to call the method at the right time. The decision test: would different arguments fix it? Yes means ISE, no means IAE.
Objects.requireNonNull is the JDK standard for null checks, throwing NPE (not IAE). Guava Preconditions provides checkArgument (throws IAE) and checkState (throws ISE) for more concise validation.
In Spring Boot at National Bank of India, IAE maps to 400 Bad Request (client error, fix your input) and ISE maps to 409 Conflict or 503 Service Unavailable (server state problem). This distinction helps the API client decide whether to fix the request or retry later.
Remember one sentence: IAE means the argument is wrong and the caller should fix it, while ISE means the object is in the wrong state and the caller should try at a different time.
---