Skip to content

Parthrajsinh1/Exception_Handling_Core_Java

Repository files navigation

Exception Handling — Core Java (Deep Dive)


Project overview

This repository contains small, focused Java programs that demonstrate and explain Java's exception-handling mechanisms. The goal is to help beginners and intermediate learners understand checked vs unchecked exceptions, throw vs throws, try / catch / finally, exception propagation, custom exceptions, and common best practices. Each file is short and targeted so you can run, inspect, and learn quickly.

Files in this repo

  • CustomChecked.java — a simple checked custom exception (extends Exception).
  • CustomUnchecked.java — a runtime/unchecked custom exception (extends RuntimeException).
  • Program01.java — basic try-catch-finally example (ArithmeticException / basic handling).
  • Program02.java — multi-catch / multiple catches / ordering and common pitfalls.
  • Program03.java — nested try / rethrowing / propagation example.
  • Throw.java — demonstrates using throw explicitly to raise exceptions.
  • Throws.java — demonstrates the throws keyword and exception propagation through method signatures.

Note: the code files are intentionally compact teaching examples. Read the "Deep explanations" section below to understand the intent and expected behavior of each program.


How to compile and run

Assuming you have JDK installed and you're inside the repo directory with the .java files at root:

# compile all .java files
javac *.java

# run examples (pick one):
java Program01
java Program02
java Program03
java Throw
java Throws

If the examples are in a package, compile and run with package paths. If you see compile errors about checked exceptions, that is intentional in some examples — they show what the compiler enforces.


Deep explanations (concepts & what to look for)

1) Checked vs Unchecked exceptions

  • Checked exceptions are subclasses of Exception (except RuntimeException). The compiler forces callers to handle them (either with try-catch or throws). Good for recoverable conditions (I/O errors, database exceptions).
  • Unchecked exceptions are subclasses of RuntimeException (and Error). They represent programming errors (null pointer, arithmetic, index out-of-bounds) and the compiler does not force handling.

Files: CustomChecked.java demonstrates declaring a checked exception class. CustomUnchecked.java demonstrates a runtime exception.

When to create custom exceptions:

  • Use custom checked exceptions when you want the caller to be forced to handle or explicitly propagate an expected, recoverable condition.
  • Use custom unchecked exceptions when a condition indicates a programmer error or unrecoverable state (invalid arguments, illegal state).

Implementation notes to check in CustomChecked.java / CustomUnchecked.java:

  • Provide the common constructors: default, String message, String message, Throwable cause, and Throwable cause — this preserves stack traces and chaining.

2) try / catch / finally

  • try wraps code that might throw; catch handles specific exception types. finally runs whether or not an exception occurred (unless the JVM exits).
  • The order of catch blocks matters — catch more specific exceptions first, then broader ones. From Java 7 on you can use multi-catch (catch (A|B ex)), but avoid combining exceptions if you need to call exception-specific methods.

File: Program01.java shows a simple try-catch-finally that handles ArithmeticException and prints a useful message and stack trace.

Common mistakes:

  • Catching Exception too early — hides specific problems.
  • Empty catch blocks (catch (Exception e) {}) — this swallows errors and makes debugging hard.

3) throw vs throws

  • throw is used to raise an exception instance in code: throw new IllegalArgumentException("bad").
  • throws goes on a method declaration to say the method may propagate (not handle) checked exceptions: void foo() throws IOException { ... }.

Files: Throw.java demonstrates throw. Throws.java demonstrates throws in a method signature and shows propagation up the call stack.

Points to observe:

  • You cannot throw a checked exception without declaring throws in the method signature or catching it locally.
  • You can throw unchecked exceptions anywhere.

4) Exception propagation and rethrowing

When an exception is not caught in a method, it propagates to the caller. Sometimes you want to catch, do cleanup or logging, and then rethrow the same or a new exception (exception translation).

File: Program03.java shows nested try-catch where inner code throws an exception, an inner catch logs something and rethrows (or wraps) it. Look for throw e; or throw new MyCheckedException("context", e);.

Best practice: When wrapping an exception, include the original as the cause (new RuntimeException("msg", original)) so stack traces remain informative.


5) Try-with-resources and suppressed exceptions (advanced)

When using resources (I/O streams, DB connections), prefer try-with-resources which automatically closes resources and correctly handles suppressed exceptions. Suppressed exceptions are those thrown while closing resources — they are attached to the primary exception and can be viewed via Throwable.getSuppressed().

Not every example in this repo uses try-with-resources, but it's an important pattern to prefer for real code that deals with AutoCloseable resources.


Per-file walkthrough (what to expect)

CustomChecked.java

  • Declares public class CustomChecked extends Exception.
  • Includes standard constructors.
  • Purpose: teach creation and usage of a checked exception. Example usage: a method might throw new CustomChecked("...reason...") and the caller must try-catch or throw it further.

CustomUnchecked.java

  • Declares public class CustomUnchecked extends RuntimeException.
  • Includes standard constructors.
  • Purpose: show an exception type that does not need throws and is used for runtime errors.

Program01.java

  • Simple arithmetic example (divide by zero) inside try.
  • catch (ArithmeticException e) prints user-friendly message and e.printStackTrace().
  • finally block prints a message to show it always runs.

Expected output (example)

Attempting division...
Caught ArithmeticException: / by zero
Finally block executed
Program ended

Program02.java

  • Example of multiple catch blocks and (possibly) a multi-catch example.
  • Shows order sensitivity and handling different exception types (e.g., NumberFormatException, ArrayIndexOutOfBoundsException).
  • Demonstrates catch (IOException | SQLException e) style when appropriate.

Program03.java

  • Demonstrates nested try blocks and rethrowing (or wrapping) an exception for higher-level context.
  • Shows how a top-level caller might handle the rethrown exception.

Throw.java

  • Demonstrates throw new IllegalArgumentException(...) and/or throw new CustomChecked(...) with appropriate method signature if a checked exception is thrown.
  • Purpose: show explicit raising of exceptions when validating arguments or state.

Throws.java

  • Demonstrates method signatures with throws CustomChecked or throws Exception and shows how the main method either handles or declares exception.
  • Purpose: teach propagation and the compiler enforcement for checked exceptions.

Sample code snippets (short, conceptual)

Custom checked exception skeleton

public class CustomChecked extends Exception {
    public CustomChecked() { super(); }
    public CustomChecked(String message) { super(message); }
    public CustomChecked(String message, Throwable cause) { super(message, cause); }
    public CustomChecked(Throwable cause) { super(cause); }
}

Throwing a checked exception (must declare or catch)

public void risky() throws CustomChecked {
    if (/* bad condition */) {
        throw new CustomChecked("something went wrong");
    }
}

Rethrowing with context

try {
    risky();
} catch (CustomChecked e) {
    // add context and rethrow
    throw new RuntimeException("High-level operation failed", e);
}

Best practices & tips (deep)

  • Prefer specific catches: catching Exception hides bugs; catch the specific exception and handle it.
  • Don't swallow exceptions: never leave empty catch blocks — at least log or rethrow.
  • Wrap with context: when rethrowing, wrap the original exception to keep the cause chain: new MyException(msg, cause).
  • Use unchecked for programmer errors: invalid arguments or illegal states should typically be unchecked.
  • Use checked for recoverable failures: I/O, network, and user-correctable issues.
  • Try-with-resources for AutoCloseable resources to prevent resource leaks and get correct suppressed-exception handling.
  • Log the stack trace when diagnosing in development; in production use structured logging and redact sensitive info.
  • Document the exception behavior in method javadocs (@throws) so callers know what to expect.

FAQ

Q: When should I create a custom exception? A: When you need to convey domain-specific error information (e.g., InsufficientBalanceException) and either force callers to handle it (checked) or convey a clear runtime error (unchecked).

Q: Is it ok to always throw RuntimeException for convenience? A: No. Overusing unchecked exceptions makes it easy to ignore error handling and can make client code brittle. Use the right tool for the job.

Q: How to preserve the original stack trace? A: Use exception chaining: new Exception("message", original) so original becomes the cause.


Troubleshooting & common compile errors

  • unreported exception CustomChecked; must be caught or declared to be thrown — fix by either wrapping the call in try-catch or declaring throws CustomChecked on the method.
  • incompatible types after multi-catch — remember in multi-catch you cannot call exception-specific methods without casting because the compile-time type is the union type.

Contribution

If you want to improve the repo:

  • Add more examples (I/O exceptions, file handling with try-with-resources, InterruptedException handling for threads, etc.).
  • Add unit tests that intentionally provoke exceptions so students can see stack traces and suppressed exceptions in action.
  • Add a docs/ folder with diagrams that show stack traces and propagation flows.

Please open a PR with clear explanations and example outputs. .

Happy deep-diving — run the examples, step through with a debugger, and inspect stack traces. If you want, I can also convert this README into a polished GitHub-flavored README with badges and screenshots.


Author: Parthrajsinh1 (project owner)

About

Here are some programs to simplify Exception Handling mechanism works in Java !

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages