Skip to content

Commit fe33a72

Browse files
committed
feat: Add exception handling demo for unchecked ArithmeticException with stack-trace printing
WHAT the code does: - Defines `CheckedUncheckedException` with three helper methods: `fun1()`, `fun2()`, `fun3()` and `main()` which calls `fun3()`. - `fun1()` performs `System.out.println(10/0);` inside a `try` block and catches `Exception`: - Prints `e.getMessage()` and `e.printStackTrace()` when the division-by-zero occurs. - `fun2()` → calls `fun1()`. `fun3()` → calls `fun2()`. `main()` → calls `fun3()`. - At runtime this demonstrates an **unchecked exception** (ArithmeticException) being thrown and caught; the stack trace shows the call chain (`fun1` ← `fun2` ← `fun3` ← `main`). WHY this matters: - Distinguishes **checked** vs **unchecked** exceptions: - Checked exceptions (e.g., `IOException`) must be declared or handled at compile time. - Unchecked exceptions (e.g., `ArithmeticException`, `NullPointerException`) happen at runtime; the compiler does not force handling. - Shows how exception handling changes program behavior from crashing to controlled error reporting. - Demonstrates propagation: even though the exception originates in `fun1()`, the stack trace reveals the full call path, which is crucial for debugging. - Important for production-quality code: deciding whether to catch, log, transform, or let the exception propagate is a key design decision. HOW it works (step-by-step): 1. `main()` calls `fun3()`. 2. `fun3()` calls `fun2()`. 3. `fun2()` calls `fun1()`. 4. `fun1()` executes `10/0` which throws `ArithmeticException`. 5. The `catch (Exception e)` in `fun1()` handles the exception: - `e.getMessage()` prints something like `/ by zero`. - `e.printStackTrace()` prints the exception type and the call stack showing where it happened. 6. Program continues after the catch block (no crash because exception was handled). TIPS, GOTCHAS & IMPROVEMENTS (production-ready and interview-smart): - **Catch the specific exception** rather than `Exception`: - Use `catch (ArithmeticException e)` so you only handle expected failures and don’t accidentally swallow other problems. - **Prefer validation to exceptions** where applicable: - If you're dividing by a variable divisor, check `if (divisor == 0)` and handle that case instead of relying on exceptions for control flow. - **Logging vs printing**: - Replace `e.printStackTrace()` with a proper logger (e.g., `Logger.error("Division failed", e)`) in real apps — it’s configurable and thread-safe. - **Don’t swallow exceptions silently**: - If a method cannot correctly handle the error, either rethrow it (`throw e;` or `throw new RuntimeException(e)`) or return an error result so the caller can decide. - **Use finally / try-with-resources** for cleanup: - When resources are involved (files, streams, DB connections) ensure they’re closed in `finally` or by try-with-resources. - **Document intention**: - If you intentionally catch an unchecked exception to keep the program running, add a comment explaining why (otherwise readers assume a bug). - **Avoid infinite or deep recursion**: - Your previous examples showed recursion issues (`fun3()` recursively calling itself). Always ensure termination conditions to avoid `StackOverflowError`. - **Unit tests**: - Add tests asserting expected behavior for exception and normal cases (use JUnit `assertThrows` for expected exceptions). Suggested improved `fun1()` (example): ```java static void fun1() { try { System.out.println(10 / 0); } catch (ArithmeticException e) { // handle the specific error System.err.println("Division by zero: " + e.getMessage()); // use a logger in real code: logger.error("Arithmetic error in fun1", e); // optionally rethrow if caller should handle it: // throw e; } } Example output (current program): / by zero java.lang.ArithmeticException: / by zero at CheckedUncheckedException.fun1(CheckedUncheckedException.java:4) at CheckedUncheckedException.fun2(CheckedUncheckedException.java:9) at CheckedUncheckedException.fun3(CheckedUncheckedException.java:13) at CheckedUncheckedException.main(CheckedUncheckedException.java:17) Use-cases / analogies: • Defensive coding: validating user inputs (e.g., divisor) before performing operations prevents runtime exceptions. • Server process: catching exceptions at the lower level and logging them prevents a whole service from crashing. • Debugging: stack traces are like breadcrumbs showing the path the program took before it failed. Short key: java-exceptions unchecked ArithmeticException catch-specific logging input-validation. Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent b1357da commit fe33a72

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed
Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
public class CheckedUncheckedException {
2-
static void fun1()
3-
{
4-
try
5-
{
2+
static void fun1() {
3+
try {
64
System.out.println(10/0);
75
}
8-
catch (Exception e)
9-
{
6+
7+
catch (Exception e) {
108
System.out.println(e.getMessage());
119
e.printStackTrace();
1210
}
1311
}
14-
static void fun2()
15-
{
12+
13+
static void fun2() {
1614
fun1();
1715
}
18-
static void fun3()
19-
{
16+
17+
static void fun3() {
2018
fun2();
2119
}
22-
public static void main(String[] args)
23-
{
20+
21+
public static void main(String[] args) {
2422
fun3();
2523
}
2624
}

0 commit comments

Comments
 (0)