Show the simplest way to define a custom unchecked exception in Java and throw it.
answer
- extends RuntimeException + super(message)
- throw new MyException("reason")
- Unchecked → no throws clause needed
- Name ends in Exception
- getMessage() returns what you passed to super
basics
~10 sCreate a class that extends RuntimeException, add a constructor that calls super(message), then throw new MyException("reason"). That's enough for a working custom exception.
solid answer
~40 sThe minimal custom exception is a class extending RuntimeException (unchecked) or Exception (checked) with at least one constructor that forwards a message to super. For example, class InvalidInputException extends RuntimeException { public InvalidInputException(String message) { super(message); } }. You throw it with throw new InvalidInputException("name must not be blank"). Because it extends RuntimeException, no throws clause or surrounding try/catch is required by the compiler. The detail message you pass to super is what getMessage() returns and what appears in the stack trace. In practice you'd also add the no-arg and cause-bearing constructors for completeness, but the single message constructor is the smallest thing that compiles, runs, and gives a useful diagnostic. Name the class with an Exception suffix so its role is obvious.
code
java · 11 linespublic class InvalidInputException extends RuntimeException {
public InvalidInputException(String message) {
super(message);
}
}
void validate(String name) {
if (name == null || name.isBlank()) {
throw new InvalidInputException("name must not be blank");
}
}go deeper
Can write a one-constructor class extending RuntimeException and throw it with a message.
Knows to add the full constructor set and the Exception naming convention, and explains why unchecked needs no throws.
Discusses when a minimal exception is appropriate vs. adding context fields, and ensures consistency with a project base exception.
Ensures even minimal exceptions fit the org's error-handling and observability conventions (codes, logging, mapping) rather than proliferating ad-hoc types.
## The goal We want the smallest amount of code that gives us a *named*, throwable, custom error type with a useful message. ## Step 1: pick a base class Every throwable type descends from `Throwable`. For application errors you extend one of: - `RuntimeException` → **unchecked** (no compiler ceremony to throw or catch it). - `Exception` → **checked** (callers must catch it or declare `throws`). For the *simplest* example we choose `RuntimeException` so we don't have to add `throws` clauses everywhere. ## Step 2: write the class with one constructor ```java public class InvalidInputException extends RuntimeException { public InvalidInputException(String message) { super(message); } } ``` That's the whole thing. Key points: - **`extends RuntimeException`** makes it a real exception type and makes it unchecked. - The **constructor takes a `String message`** and passes it to `super(message)`. `super` here is `RuntimeException`'s constructor, which ultimately stores the message in `Throwable`. - We don't store the message ourselves — `Throwable` does, and exposes it via `getMessage()`. - The **`Exception` suffix** in the class name is a naming convention so readers instantly recognize its purpose. ## Step 3: throw it ```java if (name == null || name.isBlank()) { throw new InvalidInputException("name must not be blank"); } ``` The `throw` keyword raises the exception. Because the type is unchecked, the enclosing method needs **no** `throws InvalidInputException` and callers need **no** try/catch — though they may still catch it if they choose. ## What you get for free By delegating to `super(message)`: - `getMessage()` returns `"name must not be blank"`. - Printing the exception or letting it propagate shows the class name and message at the top of the stack trace, e.g. `InvalidInputException: name must not be blank`, followed by the call stack — invaluable for debugging. ## Going just slightly beyond minimal The single-constructor version compiles and runs, but production code usually adds the other conventional constructors (no-arg, message+cause, cause-only) so the type supports **chaining** and matches the `Throwable` shape libraries expect: ```java public class InvalidInputException extends RuntimeException { public InvalidInputException() { super(); } public InvalidInputException(String message) { super(message); } public InvalidInputException(String message, Throwable cause) { super(message, cause); } public InvalidInputException(Throwable cause) { super(cause); } } ``` But for understanding the *minimum*, remember: **extend a base exception + one constructor that calls `super(message)` + `throw new ...`**.
- Do you need a try/catch when throwing this custom exception?No. Because it extends RuntimeException it's unchecked, so the compiler doesn't require a surrounding try/catch or a throws clause. Callers may still catch it if they want to handle it.
- What would change to make it a checked exception instead?Extend Exception instead of RuntimeException. Then any method that can throw it must catch it or declare it with throws, and callers are forced to handle it.
saying these in an interview costs you the question
- Storing the message in your own field instead of calling super(message)
- Adding a throws clause for an unchecked exception (unnecessary)
- Forgetting the Exception naming suffix
- Thinking you must override toString() to see the message — Throwable already prints it