Java / Java 21 Interview Questions
What are the best practices for exception handling in Java?
Exception handling design is a common interview discussion topic. Java distinguishes checked exceptions (must be declared or caught — compiler enforces), unchecked (RuntimeException subclasses), and errors (JVM-level, not catchable in normal code).
// 1. Prefer specific exceptions over general ones
// Bad: catch (Exception e) { ... }
// Good: catch (IOException | ParseException e) { ... }
// 2. Try-with-resources for AutoCloseable resources
try (var conn = ds.getConnection();
var stmt = conn.prepareStatement(sql)) {
// Both closed automatically in reverse order
} catch (SQLException e) {
throw new DataAccessException("Query failed", e); // preserve cause
}
// 3. Wrap exceptions to maintain abstraction layers
// A service layer should not leak SQLException to the web layer
public User findUser(long id) {
try {
return repository.findById(id);
} catch (SQLException e) {
throw new ServiceException("User lookup failed for id=" + id, e);
}
}
// 4. Never swallow exceptions silently
// Bad:
try { riskyOp(); } catch (Exception e) { /* ignore */ }
// Good: at minimum, log
try { riskyOp(); } catch (Exception e) { log.error("Failed", e); throw e; }
// 5. Checked vs unchecked — modern advice
// Use checked: caller CAN and SHOULD recover (FileNotFoundException)
// Use unchecked: programming error or unrecoverable (NullPointer, IllegalArgument)
// 6. Custom exceptions — extend RuntimeException for most domain errors
public class UserNotFoundException extends RuntimeException {
private final long userId;
public UserNotFoundException(long userId) {
super("User not found: " + userId);
this.userId = userId;
}
public long getUserId() { return userId; }
}Multi-catch (catch (IOException | ParseException e)) was added in Java 7 and reduces boilerplate when handling multiple exception types with identical recovery logic. The caught variable is implicitly final in a multi-catch.
More Related questions...