Error Handling in Java: try/catch and Beyond — A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Error Handling in Java: try/catch and Beyond — from A to Z



Error handling is one of the key concepts in Java that every developer must master. Unlike many languages, Java offers a strict and well-thought-out exception system that allows you to write reliable and predictable code. In this article, we will cover everything: from the basic try/catch to advanced mechanisms such as try-with-resources and custom exceptions.



1. Basics: what are exceptions and the class hierarchy



An exception is an event that disrupts the normal flow of program execution. In Java, all exceptions are objects of classes that inherit from Throwable. The main branches of the hierarchy are:



  • Error — critical problems that are typically not handled (e.g., OutOfMemoryError).
  • Exception — exceptions that the program can handle.
  • RuntimeException (a subclass of Exception) — runtime exceptions that do not need to be checked at compile time.


All exceptions are divided into two types:

  • Checked — must be handled. The compiler will not compile the code if you do not handle them with try/catch or declare them with throws. Examples: IOException, SQLException.
  • Unchecked — inherit from RuntimeException. They do not need to be explicitly handled. Examples: NullPointerException, ArithmeticException.


2. The main mechanism: try, catch, finally



The basic exception handling block consists of three parts:



try {    // Code that may throw an exception    int result = 10 / 0;} catch (ArithmeticException e) {    // Exception handling    System.err.println("Error: division by zero!");} finally {    // This block always executes (even if an exception occurred)    System.out.println("Finally block executed.");}


Important points:

  • The catch block can be one or several for different exception types.
  • The finally block is optional but useful for closing resources (files, connections).
  • If an exception is not caught, it propagates up the call stack.


Multi-catch (Java 7+) — allows catching multiple exception types in one block:



try {    // code} catch (IOException | SQLException e) {    System.err.println("I/O or SQL error: " + e.getMessage());}


3. Try-with-resources: automatic resource closing



Starting from Java 7, the try-with-resources mechanism was introduced, which automatically closes resources that implement the AutoCloseable (or Closeable) interface. This eliminates the need to write finally for closing files, sockets, etc.



try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {    String line = reader.readLine();    System.out.println(line);} catch (IOException e) {    System.err.println("File reading error: " + e.getMessage());} // reader is closed automatically


Advantages:

  • Code becomes cleaner and shorter.
  • Resources are closed in the correct order (reverse order of their creation).
  • If an exception is thrown both in the try block and during closing, the suppressed exception is added to the main one.


You can declare multiple resources separated by a semicolon:



try (BufferedReader br = new BufferedReader(new FileReader("in.txt"));     BufferedWriter bw = new BufferedWrite                

Blogs

Book Recommendations