Master Java Exception Handling: 10 Best Practices Every Developer Should Follow

This article presents ten essential Java exception‑handling best practices—including proper resource cleanup, using specific exception types, documenting throws clauses, providing clear messages, catching the most specific exceptions first, avoiding Throwable, logging wisely, and preserving original causes—to improve code readability, reliability, and maintainability.

Programmer DD
Programmer DD
Programmer DD
Master Java Exception Handling: 10 Best Practices Every Developer Should Follow

Handling exceptions in Java is not a trivial task; even experienced developers often spend considerable time deciding which exceptions to handle and how.

Most development teams establish their own rules for exception handling, and these rules can vary widely.

This article outlines several best‑practice guidelines widely adopted by many teams.

Clean up resources in a finally block or use try‑with‑resources

A common mistake is closing resources like InputStream at the end of the try block, which prevents the close operation from running if an exception occurs.

public void doNotCloseResourceInTry() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);
        // use the inputStream to read a file
        // do NOT do this
        inputStream.close();
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

The above code works only when no exception is thrown. If an exception occurs, the close statement is skipped and the resource is not released.

The proper approach is to place cleanup code in a finally block or to use the try‑with‑resources statement.

public void closeResourceInFinally() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error(e);
            }
        }
    }
}

public void automaticallyCloseResource() {
    File file = new File("./tmp.txt");
    try (FileInputStream inputStream = new FileInputStream(file)) {
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

Declare the most specific exception

Prefer the most specific exception type in method signatures to make the code easier to understand.

public void doNotDoThis() throws Exception {
    ...
}

public void doThis() throws NumberFormatException {
    ...
}

For example, NumberFormatException clearly indicates a numeric format error.

Document exceptions in Javadoc

When a method declares that it throws an exception, add a Javadoc @throws entry describing the circumstances.

/**
 * This method does something extremely useful ...
 *
 * @param input
 * @throws MyBusinessException if ... happens
 */
public void doSomething(String input) throws MyBusinessException {
    ...
}

Include descriptive information when throwing

Provide a concise description (one or two sentences) that clarifies the problem, even though the exception class name already conveys the basic reason.

try {
    new Long("xyz");
} catch (NumberFormatException e) {
    log.error(e);
}

If the exception name is not self‑explanatory, add a specific message.

Catch the most specific exception first

Catching a broad exception before a specific one prevents the specific handler from ever executing.

public void catchMostSpecificExceptionFirst() {
    try {
        doSomething("A message");
    } catch (NumberFormatException e) {
        log.error(e);
    } catch (IllegalArgumentException e) {
        log.error(e);
    }
}

Never catch Throwable

Throwable

includes both exceptions and errors; catching it can swallow unrecoverable JVM errors. Only catch it if you are absolutely sure you can handle every possible error.

public void doNotCatchThrowable() {
    try {
        // do something
    } catch (Throwable t) {
        // don't do this!
    }
}

Do not ignore exceptions

Never leave a catch block empty or without logging; unexpected exceptions can surface later and make debugging difficult. At a minimum, record the exception.

public void logAnException() {
    try {
        // do something
    } catch (NumberFormatException e) {
        log.error("This should never happen: " + e);
    }
}

Do not log and rethrow the same exception

Logging an exception and then rethrowing it leads to duplicate log entries. Instead, either let the caller handle it or wrap it in a custom exception.

try {
    new Long("xyz");
} catch (NumberFormatException e) {
    log.error(e);
    throw e;
}

When wrapping, preserve the original cause

Wrap standard exceptions in custom ones to add context, but always pass the original exception as the cause so that stack traces remain complete.

public void wrapException(String input) throws MyBusinessException {
    try {
        // do something
    } catch (NumberFormatException e) {
        throw new MyBusinessException("A message that describes the error.", e);
    }
}

Conclusion

When throwing or catching exceptions, many considerations affect code readability and API usability. Treat exceptions not only as an error‑control mechanism but also as a communication medium; discussing these best practices and establishing team guidelines helps everyone understand and apply them consistently.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaException Handlingbest practices
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.