[{"data":1,"prerenderedAt":170},["ShallowReactive",2],{"qa-\u002Fjava\u002Fexceptions\u002Fexception-handling":3},{"page":4,"siblings":165,"blog":167},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":157,"seo":158,"seoDescription":159,"stem":160,"subtopic":6,"topic":161,"topicSlug":162,"updated":163,"__hash__":164},"qa\u002Fjava\u002Fexceptions\u002Fexception-handling.md","Exception Handling",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Java","java",{},true,1,"\u002Fjava\u002Fexceptions\u002Fexception-handling",[23,28,32,36,40,44,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153],{"id":24,"difficulty":25,"q":26,"a":27},"what-is-exception","easy","What is an exception in Java?","An exception is an **object representing an abnormal event** that disrupts\nnormal flow — a division by zero, a missing file, a null dereference. When one\noccurs, the JVM creates an exception object and **propagates it up the call\nstack** until a matching `catch` handles it, or the thread terminates.\n\n```java\ntry {\n  int x = 10 \u002F 0;          \u002F\u002F throws ArithmeticException\n} catch (ArithmeticException e) {\n  System.out.println(\"Caught: \" + e.getMessage()); \u002F\u002F \"\u002F by zero\"\n}\n```\n\nExceptions separate error-handling code from the main logic and carry context\n(message + stack trace) to help diagnose what went wrong.\n",{"id":29,"difficulty":14,"q":30,"a":31},"exception-hierarchy","What does the Java exception hierarchy look like?","Everything throwable descends from **`Throwable`**, which splits into two\nbranches:\n\n- **`Error`** — serious problems the application shouldn't catch\n  (`OutOfMemoryError`, `StackOverflowError`). Unchecked.\n- **`Exception`** — conditions a program may want to handle.\n  - **`RuntimeException`** and its subclasses are **unchecked**.\n  - All other `Exception` subclasses are **checked**.\n\n```\nThrowable\n├── Error              (unchecked — don't catch)\n└── Exception\n    ├── RuntimeException   (unchecked)\n    └── IOException, SQLException... (checked)\n```\n\nSo \"checked vs unchecked\" is purely about whether the class sits under\n`RuntimeException`\u002F`Error` (unchecked) or elsewhere under `Exception` (checked).\n",{"id":33,"difficulty":14,"q":34,"a":35},"checked-vs-unchecked","What is the difference between checked and unchecked exceptions?","- **Checked** exceptions (subclasses of `Exception`, excluding\n  `RuntimeException`) are verified by the **compiler**: a method must either\n  `catch` them or declare `throws`. They represent recoverable, expected\n  conditions (`IOException`, `SQLException`).\n- **Unchecked** exceptions (`RuntimeException`\u002F`Error` subclasses) are **not**\n  compiler-enforced — usually programming bugs (`NullPointerException`,\n  `IllegalArgumentException`, `ArrayIndexOutOfBoundsException`).\n\n```java\nvoid read() throws IOException {     \u002F\u002F checked -> must declare or catch\n  Files.readString(Path.of(\"x\"));\n}\nvoid bug() {\n  String s = null;\n  s.length();                        \u002F\u002F unchecked -> no declaration required\n}\n```\n\nGuideline: checked for conditions callers can reasonably recover from;\nunchecked for bugs and contract violations.\n",{"id":37,"difficulty":14,"q":38,"a":39},"error-vs-exception","What is the difference between Error and Exception?","Both extend `Throwable`, but:\n\n- **`Error`** signals a serious, usually **unrecoverable** JVM\u002Fsystem problem —\n  `OutOfMemoryError`, `StackOverflowError`, `NoClassDefFoundError`. Applications\n  **should not catch** these; there's typically nothing useful to do.\n- **`Exception`** signals an **application-level** condition that code may\n  reasonably handle.\n\n```java\ntry {\n  recurse();                  \u002F\u002F infinite recursion\n} catch (StackOverflowError e) {\n  \u002F\u002F technically possible, but a code smell — don't rely on this\n}\n```\n\nBoth are unchecked (well, `Error` is), but the intent differs: `Error` = \"the\nplatform is broken\"; `Exception` = \"your program hit a handleable situation.\"\n",{"id":41,"difficulty":25,"q":42,"a":43},"try-catch-finally","What are try, catch and finally blocks?","- **`try`** — wraps code that might throw.\n- **`catch`** — handles a specific exception type (you can have several).\n- **`finally`** — runs **always**, whether or not an exception occurred (and\n  even after a `return`) — for cleanup like closing resources.\n\n```java\ntry {\n  risky();\n} catch (IOException e) {\n  log(e);\n} finally {\n  cleanup();   \u002F\u002F runs no matter what\n}\n```\n\nA `try` needs at least one `catch` **or** a `finally`. `catch` blocks are checked\ntop-down, so order **subclasses before superclasses**.\n",{"id":45,"difficulty":46,"q":47,"a":48},"finally-always-runs","hard","Does finally always run? Are there exceptions?","`finally` runs after the `try`\u002F`catch` in virtually all cases — including when\nthe `try` or `catch` executes a `return`, `break`, or `continue`. The **only**\nways to skip it: `System.exit()`, the JVM crashing, an infinite loop\u002Fdeadlock in\nthe `try`, or the thread being killed.\n\n```java\nint f() {\n  try {\n    return 1;     \u002F\u002F evaluated...\n  } finally {\n    System.out.println(\"still runs\"); \u002F\u002F ...but finally runs before returning\n  }\n}\n```\n\nBeware: a `return` (or `throw`) **inside `finally`** overrides the try's return\nand **swallows pending exceptions** — a notorious bug, so never return\u002Fthrow\nfrom `finally`.\n",{"id":50,"difficulty":14,"q":51,"a":52},"try-with-resources","What is try-with-resources?","A `try` with resources declared in parentheses **auto-closes** them when the\nblock exits — normally or via exception — as long as they implement\n`AutoCloseable`. It replaces verbose `finally { x.close(); }` blocks and avoids\nleaks.\n\n```java\ntry (var br = Files.newBufferedReader(path);\n     var conn = dataSource.getConnection()) {\n  return br.readLine();\n}   \u002F\u002F br and conn closed automatically, in reverse order\n```\n\nResources close in **reverse order** of declaration. It also handles the case\nwhere both the body *and* `close()` throw — see suppressed exceptions.\n",{"id":54,"difficulty":14,"q":55,"a":56},"autocloseable","What is AutoCloseable and how do you use it?","`AutoCloseable` is the interface (one method, `close()`) that makes a class\neligible for **try-with-resources**. Implement it for any resource that needs\ndeterministic cleanup — connections, streams, locks.\n\n```java\nclass Connection implements AutoCloseable {\n  Connection() { System.out.println(\"open\"); }\n  public void close() { System.out.println(\"closed\"); }\n}\ntry (Connection c = new Connection()) {\n  \u002F\u002F use c\n} \u002F\u002F close() called automatically\n```\n\n`Closeable` (from `java.io`) extends `AutoCloseable` but narrows `close()` to\nthrow `IOException`. Prefer `AutoCloseable` for general resources.\n",{"id":58,"difficulty":14,"q":59,"a":60},"multi-catch","What is multi-catch and when is it useful?","Multi-catch (Java 7+) handles **several exception types in one `catch`** using\nthe `|` separator, when the handling logic is identical — reducing duplication.\n\n```java\ntry {\n  parseAndStore();\n} catch (IOException | SQLException e) {   \u002F\u002F one handler for both\n  log.error(\"operation failed\", e);\n  throw new ServiceException(e);\n}\n```\n\nRules: the types must **not be subclasses of one another** (redundant), and the\ncaught variable `e` is **implicitly final**. Use it to collapse copy-pasted\ncatch blocks.\n",{"id":62,"difficulty":25,"q":63,"a":64},"throw-vs-throws","What is the difference between throw and throws?","- **`throw`** is a **statement** that actually raises an exception object, now.\n- **`throws`** is a **method declaration** clause announcing which checked\n  exceptions the method may propagate to its caller.\n\n```java\nvoid withdraw(int amt) throws InsufficientFundsException { \u002F\u002F declares\n  if (amt > balance) {\n    throw new InsufficientFundsException(); \u002F\u002F raises\n  }\n}\n```\n\nMnemonic: `throw` *does* it (one object), `throws` *warns about* it (a list of\ntypes). You can `throw` unchecked exceptions without declaring them.\n",{"id":66,"difficulty":14,"q":67,"a":68},"custom-exception","How do you create a custom exception?","Extend `Exception` (for checked) or `RuntimeException` (for unchecked), and\nprovide constructors that pass the message and cause to `super`.\n\n```java\npublic class InsufficientFundsException extends RuntimeException {\n  private final int shortfall;\n  public InsufficientFundsException(int shortfall) {\n    super(\"Short by \" + shortfall + \" cents\");\n    this.shortfall = shortfall;\n  }\n  public int getShortfall() { return shortfall; }\n}\n```\n\nCustom exceptions let you carry **domain-specific data** and let callers\n`catch` precisely. Prefer **unchecked** for programming\u002Fbusiness errors unless\nthe caller can genuinely recover (then checked).\n",{"id":70,"difficulty":14,"q":71,"a":72},"exception-chaining","What is exception chaining (the cause)?","Exception chaining wraps a low-level exception inside a higher-level one while\n**preserving the original as the \"cause\"**, so the full diagnostic trail\nsurvives. Pass the cause to the constructor or `initCause`.\n\n```java\ntry {\n  jdbc.query();\n} catch (SQLException e) {\n  throw new DataAccessException(\"load failed\", e); \u002F\u002F e becomes the cause\n}\n```\n\nThe printed stack trace shows `Caused by: java.sql.SQLException...`. Chaining\nlets you translate exceptions across abstraction layers without losing the root\ncause — far better than catching and re-throwing a bare new exception.\n",{"id":74,"difficulty":46,"q":75,"a":76},"swallowing","What does it mean to \"swallow\" an exception and why is it bad?","Swallowing is catching an exception and **doing nothing** (or only an empty\nblock), hiding the failure so the program continues in a possibly broken state\nand you lose all diagnostic information.\n\n```java\n\u002F\u002F swallowed — silent failure, impossible to debug\ntry { risky(); } catch (Exception e) { }\n\n\u002F\u002F at minimum, log it (and preserve the stack trace)\ntry { risky(); } catch (Exception e) {\n  log.error(\"risky() failed\", e);\n  throw e;                 \u002F\u002F or wrap\u002Frethrow if you can't handle it\n}\n```\n\nRule: never have an empty catch. Either **handle** it meaningfully, **log** it,\nor **rethrow**. Empty catches are one of the most damaging anti-patterns in\nproduction code.\n",{"id":78,"difficulty":14,"q":79,"a":80},"catch-order","Why does catch block order matter?","`catch` blocks are evaluated **top to bottom**, and the first matching type\nwins. So a **more specific** exception must come **before** its superclass —\notherwise the broad catch shadows the specific one and the compiler reports\n\"exception has already been caught.\"\n\n```java\ntry {\n  read();\n} catch (FileNotFoundException e) {  \u002F\u002F specific first\n  \u002F\u002F handle missing file\n} catch (IOException e) {            \u002F\u002F broader after\n  \u002F\u002F handle other I\u002FO errors\n}\n```\n\nReversing them (`IOException` first) is a **compile error**, because\n`FileNotFoundException` could never be reached.\n",{"id":82,"difficulty":25,"q":83,"a":84},"npe-causes","What causes a NullPointerException and how do you prevent it?","An NPE happens when you **dereference `null`** — call a method, access a field,\nindex an array, or unbox a null wrapper.\n\n```java\nString s = map.get(\"missing\"); \u002F\u002F null\ns.length();                    \u002F\u002F NullPointerException\n```\n\nPrevention: validate inputs (`Objects.requireNonNull`), use `Optional` for\nmaybe-absent values, prefer constants on the left of `equals`\n(`\"x\".equals(s)`), use `getOrDefault`, and embrace **Java 14+ helpful NPE\nmessages** which name the exact expression that was null\n(`Cannot invoke \"String.length()\" because \"s\" is null`).\n",{"id":86,"difficulty":14,"q":87,"a":88},"optional","How does Optional help with null handling?","`Optional\u003CT>` is a container that **explicitly represents \"value or absent,\"**\nforcing callers to deal with the empty case instead of risking an NPE on a\nsurprise null.\n\n```java\nOptional\u003CUser> user = repo.findById(id);\nString name = user.map(User::name)\n                  .orElse(\"unknown\");        \u002F\u002F default if absent\nuser.ifPresent(u -> sendEmail(u));           \u002F\u002F act only if present\n```\n\nBest practices: use it as a **return type** for \"might not find one\"; **don't**\nuse it for fields, parameters, or collections (return an empty collection\ninstead); and avoid `.get()` without checking (`isPresent`\u002F`orElseThrow`).\n",{"id":90,"difficulty":25,"q":91,"a":92},"stack-trace","What is a stack trace and how do you read it?","A stack trace is the **snapshot of the call stack** at the moment an exception\nwas created — it lists, top to bottom, the method calls from where the\nexception was thrown back up to the entry point.\n\n```\njava.lang.NullPointerException: ... \"user\" is null\n    at com.app.Service.process(Service.java:42)   \u003C- where it was thrown\n    at com.app.Controller.handle(Controller.java:18)\n    at com.app.Main.main(Main.java:9)\nCaused by: java.sql.SQLException: ...             \u003C- original cause\n```\n\nRead the **top frame** for where it blew up, and follow **`Caused by:`** down to\nthe root cause. Print it with `e.printStackTrace()` or, better, `log.error(msg,\ne)`.\n",{"id":94,"difficulty":46,"q":95,"a":96},"finally-return-trap","What happens when both try and finally have a return?","A `return` in `finally` **overrides** any return or exception from the `try`\u002F\n`catch` — the try's pending result (or thrown exception) is **discarded\nsilently**. This is a subtle, dangerous bug.\n\n```java\nint f() {\n  try {\n    return 1;\n  } finally {\n    return 2;   \u002F\u002F method returns 2; the \"return 1\" is lost\n  }\n}\nint g() {\n  try {\n    throw new RuntimeException();\n  } finally {\n    return 0;   \u002F\u002F swallows the exception entirely\n  }\n}\n```\n\nNever put `return`\u002F`throw`\u002F`break` in `finally`. Use `finally` strictly for\ncleanup, not control flow.\n",{"id":98,"difficulty":46,"q":99,"a":100},"suppressed-exceptions","What are suppressed exceptions?","In try-with-resources, if the **body throws** *and* `close()` also throws, Java\nkeeps the body's exception as primary and attaches the close exception as a\n**suppressed** exception (so neither is lost). You retrieve them via\n`getSuppressed()`.\n\n```java\ntry (AutoCloseable r = () -> { throw new IOException(\"close failed\"); }) {\n  throw new RuntimeException(\"body failed\"); \u002F\u002F primary\n}\n\u002F\u002F RuntimeException propagates; the IOException is in getSuppressed()\n```\n\nBefore try-with-resources, a `close()` exception in a manual `finally` would\n*replace* the original — hiding the real cause. Suppression fixes that. The\nprintout shows `Suppressed:` beneath the main trace.\n",{"id":102,"difficulty":14,"q":103,"a":104},"rethrow","What are the ways to rethrow an exception?","- **Rethrow as-is** — let it propagate after partial handling (log, then\n  `throw e`).\n- **Wrap and rethrow** — translate to a higher-level type, preserving the cause\n  (`throw new ServiceException(e)`).\n- **Rethrow a different type** — only when it improves the abstraction.\n\n```java\ntry {\n  repo.save(order);\n} catch (SQLException e) {\n  metrics.increment(\"save.failure\");\n  throw new PersistenceException(\"could not save order\", e); \u002F\u002F wrap + chain\n}\n```\n\nAlways pass the original as the **cause** when wrapping, so debugging info\nsurvives. Don't catch just to rethrow the *same* type with no added value.\n",{"id":106,"difficulty":14,"q":107,"a":108},"best-practices","What are best practices for exception handling?","- **Catch specific** exceptions, not bare `Exception`\u002F`Throwable`.\n- **Never swallow** — handle, log, or rethrow.\n- **Throw early, catch late** — validate inputs at the boundary; handle where\n  you have context to recover.\n- **Don't use exceptions for control flow** (they're expensive and obscure\n  intent).\n- **Preserve the cause** when wrapping.\n- **Clean up with try-with-resources**, not manual `finally`.\n- Include **useful messages** with context.\n\n```java\n\u002F\u002F specific, contextual, chained\ncatch (IOException e) {\n  throw new ConfigException(\"failed to load \" + path, e);\n}\n```\n",{"id":110,"difficulty":46,"q":111,"a":112},"exception-performance","Why are exceptions expensive, and what is the cost?","The main cost is **capturing the stack trace** when the exception is\nconstructed — the JVM walks the entire call stack and records each frame. The\n`throw`\u002F`catch` mechanism itself is cheap; building the trace is not. So using\nexceptions for ordinary control flow (e.g. loop termination) is slow.\n\n```java\n\u002F\u002F for hot paths where the trace isn't needed, you can disable it:\nclass FastException extends RuntimeException {\n  FastException() { super(null, null, false, false); } \u002F\u002F no stack trace\n}\n```\n\nGuidance: reserve exceptions for **exceptional** conditions; use return values,\n`Optional`, or sentinels for expected outcomes. Don't catch-and-ignore in tight\nloops.\n",{"id":114,"difficulty":14,"q":115,"a":116},"custom-checked-or-unchecked","Should a custom exception be checked or unchecked?","Decide by whether the **caller can reasonably recover**:\n\n- **Checked** (`extends Exception`) — recoverable, expected conditions the\n  caller should be forced to handle (e.g. `FileNotFoundException`-like cases).\n- **Unchecked** (`extends RuntimeException`) — programming errors, contract\n  violations, or failures the caller usually can't fix (validation,\n  configuration, most business-rule violations).\n\n```java\n\u002F\u002F recoverable -> checked\nclass RetryableNetworkException extends Exception { }\n\u002F\u002F bug \u002F unrecoverable -> unchecked\nclass InvalidConfigException extends RuntimeException { }\n```\n\nModern frameworks (Spring, etc.) lean heavily toward **unchecked** to avoid\n`throws` clutter, translating low-level checked exceptions into runtime ones.\n",{"id":118,"difficulty":46,"q":119,"a":120},"catch-throwable","Why should you avoid catching Throwable or Exception broadly?","Catching `Throwable` also catches **`Error`s** (`OutOfMemoryError`,\n`StackOverflowError`) that you can't sensibly recover from and may make things\nworse. Catching `Exception` broadly hides bugs (an unexpected\n`NullPointerException` gets swallowed by a handler meant for I\u002FO errors).\n\n```java\n\u002F\u002F too broad — masks programming bugs and serious errors\ntry { work(); } catch (Throwable t) { \u002F* keep going *\u002F }\n\n\u002F\u002F catch what you can actually handle\ntry { work(); } catch (IOException e) { recover(e); }\n```\n\nCatch the **narrowest** type that you genuinely know how to handle; let\neverything else propagate to a top-level handler.\n",{"id":122,"difficulty":14,"q":123,"a":124},"exception-translation","What is exception translation across layers?","Exception translation means **converting low-level exceptions into ones\nappropriate to the current abstraction layer**, so callers aren't coupled to\nimplementation details (a service shouldn't leak `SQLException`).\n\n```java\n\u002F\u002F persistence layer hides JDBC details from the service layer\ntry {\n  return jdbcTemplate.query(sql);\n} catch (SQLException e) {\n  throw new RepositoryException(\"query failed\", e); \u002F\u002F translate + chain\n}\n```\n\nAlways keep the original as the cause. This is exactly what Spring's\n`DataAccessException` hierarchy does — translating vendor-specific SQL errors\ninto a consistent, unchecked API.\n",{"id":126,"difficulty":14,"q":127,"a":128},"assert","What is the assert keyword and how does it relate to exceptions?","`assert` checks an invariant that should *always* be true; if false it throws an\n`AssertionError`. Assertions are **disabled by default** at runtime (enable with\nthe `-ea` JVM flag), so they're for **catching developer bugs during\ndevelopment\u002Ftesting**, not validating production input.\n\n```java\nassert index >= 0 : \"index must be non-negative, got \" + index;\n```\n\nBecause they can be turned off, **never** use `assert` for argument validation\nor anything with side effects — use `if (...) throw new\nIllegalArgumentException(...)` for real input checks.\n",{"id":130,"difficulty":14,"q":131,"a":132},"nested-try","How do nested try blocks and exception propagation work?","A `try` can contain another `try`. If an inner block doesn't catch an\nexception, it **propagates outward** to the nearest enclosing handler — and\nkeeps unwinding the stack until something catches it or the thread dies.\n\n```java\ntry {\n  try {\n    throw new IllegalStateException(\"inner\");\n  } finally {\n    System.out.println(\"inner finally\"); \u002F\u002F runs during unwind\n  }\n} catch (IllegalStateException e) {\n  System.out.println(\"caught in outer\"); \u002F\u002F handled here\n}\n```\n\nDuring propagation, every `finally` along the way still executes. This unwinding\nis how an exception thrown deep in the call stack reaches a top-level handler.\n",{"id":134,"difficulty":46,"q":135,"a":136},"uncaught-handler","What happens to an uncaught exception in a thread?","If an exception propagates out of a thread's `run`\u002F`main` without being caught,\nthe thread **terminates**, and the JVM hands the exception to that thread's\n**`UncaughtExceptionHandler`** (by default printing the stack trace to\n`System.err`). Other threads keep running; the **whole JVM only exits if it was\nthe last non-daemon thread**.\n\n```java\nThread.setDefaultUncaughtExceptionHandler((t, e) ->\n    log.error(\"Uncaught in \" + t.getName(), e));\n```\n\nSetting a handler is essential for background threads, whose failures would\notherwise vanish silently.\n",{"id":138,"difficulty":14,"q":139,"a":140},"illegalargument-vs-illegalstate","When do you use IllegalArgumentException vs IllegalStateException?","Both are standard unchecked exceptions for **precondition violations**:\n\n- **`IllegalArgumentException`** — a **method argument** is invalid (wrong\n  value\u002Frange).\n- **`IllegalStateException`** — the **object is in the wrong state** for the\n  operation, regardless of the arguments.\n\n```java\nvoid setAge(int age) {\n  if (age \u003C 0) throw new IllegalArgumentException(\"age \u003C 0: \" + age);\n}\nvoid start() {\n  if (running) throw new IllegalStateException(\"already started\");\n}\n```\n\nUse the built-in exceptions (plus `NullPointerException` for null args,\nidiomatically via `Objects.requireNonNull`) rather than inventing custom ones\nfor these common cases.\n",{"id":142,"difficulty":14,"q":143,"a":144},"finally-resource-leak","Why is manual finally cleanup error-prone compared to try-with-resources?","Manual cleanup in `finally` is verbose and easy to get wrong: you must\nnull-check, nest try\u002Fcatch around `close()`, and handle the case where `close()`\nitself throws (which would hide the original exception). Multiple resources\nmultiply the boilerplate.\n\n```java\n\u002F\u002F error-prone manual style\nBufferedReader br = null;\ntry {\n  br = Files.newBufferedReader(path);\n} finally {\n  if (br != null) br.close(); \u002F\u002F close() can throw and mask the real error\n}\n\n\u002F\u002F correct, concise, handles suppression\ntry (var br = Files.newBufferedReader(path)) { }\n```\n\nTry-with-resources closes in the right order, handles nulls, and records\nsuppressed exceptions — strictly better.\n",{"id":146,"difficulty":46,"q":147,"a":148},"rethrow-precise","What is more precise rethrow analysis (Java 7+)?","Since Java 7, the compiler analyzes which checked exceptions can **actually**\nflow out of a `try`, so you can catch a broad type but **rethrow with a\nnarrower `throws`** clause — as long as the caught variable is effectively\nfinal.\n\n```java\nvoid m() throws IOException, SQLException {  \u002F\u002F precise, not \"throws Exception\"\n  try {\n    if (cond) throw new IOException();\n    else throw new SQLException();\n  } catch (Exception e) {   \u002F\u002F catch broadly...\n    log(e);\n    throw e;                \u002F\u002F ...rethrow: compiler knows it's IOException|SQLException\n  }\n}\n```\n\nBefore Java 7 you'd have been forced to declare `throws Exception`. This lets you\nlog centrally while keeping precise method signatures.\n",{"id":150,"difficulty":46,"q":151,"a":152},"exception-in-static-init","What happens if an exception is thrown in a static initializer?","If a `static` initializer (or static field initialization) throws, the JVM wraps\nit in an **`ExceptionInInitializerError`** and the class **fails to initialize**.\nWorse, the class is marked unusable: any later attempt to use it throws\n**`NoClassDefFoundError`**.\n\n```java\nclass Config {\n  static final int VALUE = compute(); \u002F\u002F if compute() throws...\n  static int compute() { throw new RuntimeException(\"boom\"); }\n}\n\u002F\u002F First use -> ExceptionInInitializerError\n\u002F\u002F Subsequent uses -> NoClassDefFoundError\n```\n\nThis is a confusing failure mode in real systems — a misconfigured static\nconstant can make a class permanently unloadable. Keep static initialization\nsimple and defensive.\n",{"id":154,"difficulty":14,"q":155,"a":156},"logging-vs-throwing","Should you log and throw, or just one?","Doing **both** at every level causes \"log spam\" — the same exception printed\nrepeatedly as it propagates. The common rule: **either handle it (and log) OR\npropagate it (and let a higher layer log)** — not both at every level.\n\n```java\n\u002F\u002F log-and-throw at every layer -> duplicated stack traces\ncatch (IOException e) { log.error(\"failed\", e); throw e; }\n\n\u002F\u002F propagate now, log once at the top-level boundary\ncatch (IOException e) { throw new ServiceException(e); }\n\u002F\u002F ... and a single handler at the controller\u002Fedge logs it\n```\n\nLog **once**, at the boundary where the exception is finally handled (e.g. a\ncontroller advice or a top-level `catch`), with full context.\n",null,{"description":11},"Java exception handling interview questions — checked vs unchecked, the exception hierarchy, try\u002Fcatch\u002Ffinally, try-with-resources, custom exceptions, chaining, and common pitfalls like swallowing exceptions.","java\u002Fexceptions\u002Fexception-handling","Exceptions","exceptions","2026-06-18","wArz93b9NB6yDuB0xDMten2Mp8DtYbRC8psG-wPq3ak",[166],{"subtopic":6,"path":21,"order":20},{"path":168,"title":169},"\u002Fblog\u002Fjava-exception-handling-checked-unchecked","Java Exception Handling — Checked vs Unchecked, try\u002Fcatch & Best Practices",1781808676685]