Java Cheatsheet
Exceptions
Use this Java reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Exception Hierarchy
Throwable ├── Error — JVM-level, don't catch (OutOfMemoryError, StackOverflowError) └── Exception ├── RuntimeException (unchecked — no throws declaration required) │ ├── NullPointerException │ ├── ArrayIndexOutOfBoundsException │ ├── ClassCastException │ ├── IllegalArgumentException │ ├── IllegalStateException │ ├── ArithmeticException │ ├── NumberFormatException │ ├── UnsupportedOperationException │ ├── IndexOutOfBoundsException │ └── ConcurrentModificationException └── (checked — must be declared or caught) ├── IOException │ ├── FileNotFoundException │ └── EOFException ├── SQLException ├── ParseException ├── InterruptedException └── CloneNotSupportedException
try / catch / finally
try { int result = 10 / 0; String s = null; s.length(); // NullPointerException } catch (ArithmeticException e) { System.out.println("Math error: " + e.getMessage()); } catch (NullPointerException e) { System.out.println("Null: " + e.getMessage()); } catch (Exception e) { // Broad catch-all (avoid if possible) e.printStackTrace(); } finally { System.out.println("Always runs — good for cleanup"); }
Order matters: catch subclass before superclass. Catching Exception first would cause compile errors for subsequent specific catches.
Multi-catch (Java 7+)
try { methodThatMayThrow(); } catch (IOException | SQLException e) { // e is effectively final here System.out.println("I/O or SQL error: " + e.getMessage()); }
try-with-resources (Java 7+)
Resources implementing AutoCloseable are automatically closed, even if an exception is thrown.
try (FileReader fr = new FileReader("file.txt"); BufferedReader br = new BufferedReader(fr)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } // fr and br are closed in reverse order automatically // Java 9+: effectively-final variable from outer scope BufferedReader br = new BufferedReader(new FileReader("file.txt")); try (br) { // no redeclare needed br.readLine(); }
Throwing Exceptions
// Throw an existing exception throw new IllegalArgumentException("Value must be positive: " + value); // Re-throw try { riskyMethod(); } catch (IOException e) { throw e; // re-throw same exception } // Wrap in a different exception (exception chaining) try { riskyMethod(); } catch (IOException e) { throw new RuntimeException("Failed to process", e); // cause preserved } // throw in a method — checked exceptions must be declared public void readFile(String path) throws IOException { throw new FileNotFoundException("Not found: " + path); }
Custom Exceptions
// Unchecked custom exception public class ValidationException extends RuntimeException { private final String field; public ValidationException(String field, String message) { super(message); this.field = field; } // Preserve cause public ValidationException(String field, String message, Throwable cause) { super(message, cause); this.field = field; } public String getField() { return field; } } // Checked custom exception public class ServiceException extends Exception { private final int errorCode; public ServiceException(int errorCode, String message) { super(message); this.errorCode = errorCode; } public ServiceException(int errorCode, String message, Throwable cause) { super(message, cause); this.errorCode = errorCode; } public int getErrorCode() { return errorCode; } } // Usage if (age < 0) throw new ValidationException("age", "Age cannot be negative");
Checked vs. Unchecked
| Checked | Unchecked (RuntimeException) |
|---|---|
Must declare with throws | No declaration required |
| Caller must catch or propagate | Caller can ignore |
| Represents recoverable failures | Represents programming errors |
IOException, SQLException | NullPointerException, IllegalArgumentException |
// Checked — must declare public String readFile(String path) throws IOException { return Files.readString(Path.of(path)); } // Unchecked — no declaration needed public int divide(int a, int b) { if (b == 0) throw new ArithmeticException("Division by zero"); return a / b; }
Exception Methods (Throwable API)
try { throw new RuntimeException("something broke"); } catch (Exception e) { e.getMessage() // "something broke" e.getLocalizedMessage() // same (can be overridden for locale) e.getCause() // the wrapped cause, or null e.getClass().getName() // "java.lang.RuntimeException" e.printStackTrace() // prints stack trace to stderr e.getStackTrace() // StackTraceElement[] String trace = Arrays.toString(e.getStackTrace()); }
Suppressed Exceptions (Java 7+)
When an exception is thrown in a finally block (or auto-close), it can suppress the original.
Exception primary = new Exception("primary"); Exception suppressed = new Exception("suppressed"); primary.addSuppressed(suppressed); try { throw primary; } catch (Exception e) { Throwable[] suppressed = e.getSuppressed(); // [suppressed] } // try-with-resources handles this automatically: // if body throws AND close() throws, close's exception is suppressed
NullPointerException Helpers (Java 14+)
String s = null; try { System.out.println(s.length()); } catch (NullPointerException e) { // Java 14+ helpful NPE messages: // "Cannot invoke "String.length()" because "s" is null" System.out.println(e.getMessage()); } // Avoid NPE with Objects utilities Objects.requireNonNull(arg, "arg must not be null"); // throws NPE with message Objects.requireNonNullElse(s, "default"); Objects.requireNonNullElseGet(s, () -> computeDefault()); Objects.isNull(s) // true Objects.nonNull(s) // false
Best Practices
// Catch specific, not broad try { ... } catch (IOException e) { ... } // good try { ... } catch (Exception e) { ... } // too broad — hides bugs // Never swallow exceptions silently catch (Exception e) { } // BAD — swallowed! catch (Exception e) { log.error(e); } // acceptable minimum // Exception chaining — always preserve cause throw new ServiceException(500, "DB failed", cause); // not just message // Use finally or try-with-resources to release resources // — never rely on GC for file handles, connections, etc. // Prefer standard exceptions over custom when appropriate: // IllegalArgumentException — bad argument // IllegalStateException — wrong object state // NullPointerException — null where non-null expected // IndexOutOfBoundsException — index out of valid range // UnsupportedOperationException — operation not supported // NoSuchElementException — requested element does not exist // ConcurrentModificationException — structural change during iteration
assert vs. Exceptions
// assert — for internal invariants (disabled in production) assert x > 0 : "x must be positive"; // exceptions — for user/caller input validation (always active) if (x <= 0) throw new IllegalArgumentException("x must be positive");
Stack Overflow and OOM
// StackOverflowError — infinite recursion void recurse() { recurse(); } // throws StackOverflowError // OutOfMemoryError — heap exhausted // Don't try to catch Error in general — the JVM state is unreliable // Exception: specific scenarios like OOM where you can free resources: try { allocateBigArray(); } catch (OutOfMemoryError e) { clearCache(); // release some memory, then rethrow or degrade gracefully throw e; }