Best Practices for Handling Exceptions in Java

This article presents comprehensive Java exception‑handling guidelines, covering why exceptions should not be ignored, how to use global handlers, capture specific exceptions, properly close I/O streams, employ try‑with‑resources, avoid returning in finally blocks, log detailed errors, and design custom exceptions for clean, maintainable backend code.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Best Practices for Handling Exceptions in Java

Common Exceptions in Daily Work

Developers often encounter exceptions such as NullPointerException, NumberFormatException, and ClassCastException, and need strategies to handle them elegantly.

1. Do Not Ignore Exceptions

Bad example:

Long id = null;
try {
    id = Long.parseLong(keyword);
} catch (NumberFormatException e) {
    // ignore exception
}

The code silently swallows parsing errors and provides no log, making troubleshooting difficult.

Good example:

Long id = null;
try {
    id = Long.parseLong(keyword);
} catch (NumberFormatException e) {
    log.info(String.format("keyword:{} 转换成Long类型失败,原因:{}", keyword, e));
}

Logging the failure allows quick identification of the problem.

2. Use a Global Exception Handler

Instead of catching exceptions in every service method, define a centralized handler with @RestControllerAdvice and @ExceptionHandler in Spring Boot.

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * Unified exception handling
     */
    @ExceptionHandler(Exception.class)
    public ApiResult handleException(Exception e) {
        if (e instanceof BusinessException) {
            BusinessException be = (BusinessException) e;
            log.info("业务异常", e);
            return ApiResultUtil.error(be.getCode(), be.getMessage());
        }
        log.error("系统异常", e);
        return ApiResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误,请联系系统管理员!");
    }
}

All controller/service try/catch blocks can be removed, and the handler will wrap and return error responses.

3. Catch Specific Exceptions

Catch concrete exceptions instead of the generic Exception to provide precise handling.

try {
    doSomething();
} catch (FileNotFoundException e) {
    log.error("文件未找到", e);
} catch (IOException e) {
    log.error("IO异常", e);
}

4. Close I/O Streams in finally

Closing streams only in the finally block ensures they are released even when an exception occurs.

FileInputStream fis = null;
try {
    File file = new File("/tmp/1.txt");
    fis = new FileInputStream(file);
    byte[] data = new byte[(int) file.length()];
    fis.read(data);
    for (byte b : data) {
        System.out.println(b);
    }
} catch (IOException e) {
    log.error("读取文件失败,原因:", e);
} finally {
    if (fis != null) {
        try {
            fis.close();
            fis = null;
        } catch (IOException e) {
            log.error("关闭IO流失败,原因:", e);
        }
    }
}

5. Prefer try‑with‑resources

Since JDK 7, resources that implement AutoCloseable can be declared in the try statement, eliminating explicit finally cleanup.

File file = new File("/tmp/1.txt");
try (FileInputStream fis = new FileInputStream(file)) {
    byte[] data = new byte[(int) file.length()];
    fis.read(data);
    for (byte b : data) {
        System.out.println(b);
    }
} catch (IOException e) {
    e.printStackTrace();
    log.error("读取文件失败,原因:", e);
}

6. Do Not Return from finally

Returning inside finally overrides any value from the try block, leading to incorrect results.

public int divide(int dividend, int divisor) {
    try {
        return dividend / divisor;
    } catch (ArithmeticException e) {
        // handle
        return -1;
    }
}

7. Avoid e.printStackTrace()

Printing stack traces to standard error can expose sensitive data and affect performance; use a logger instead.

try {
    doSomething();
} catch (IOException e) {
    log.error("doSomething处理失败,原因:", e);
}

8. Log Detailed Exception Information

Log both the message and the stack trace to capture the full context.

try {
    double b = 1/0;
} catch (ArithmeticException e) {
    log.error("处理失败,原因:", e);
}

9. Do Not Catch and Immediately Rethrow

Catching an exception only to rethrow it after logging causes duplicate logs.

try {
    doSomething();
} catch (ArithmeticException e) {
    log.error("doSomething处理失败,原因:", e);
    throw e;
}

10. Prefer Standard Exceptions

Reuse Java’s built‑in exceptions instead of creating custom ones when they convey the same meaning.

if (value < 0) {
    throw new IllegalArgumentException("值不能为负");
}

11. Document Thrown Exceptions

Javadoc should include @throws tags to describe possible exceptions.

/**
 * 处理用户数据
 * @param value 用户输入参数
 * @return 值
 * @throws BusinessException 业务异常
 */
public int doSomething(String value) throws BusinessException {
    // 业务逻辑
    return 1;
}

12. Do Not Use Exceptions for Flow Control

Using try/catch to decide program flow is inefficient; validate inputs before parsing.

Long id = checkValueType(idStr) ? Long.parseLong(idStr) : 1001;

13. Custom Exceptions When Necessary

If standard exceptions are insufficient, define a custom exception with additional fields such as an error code.

@AllArgsConstructor
@Data
public class BusinessException extends RuntimeException {
    private static final long serialVersionUID = -6735897190745766939L;
    private int code;
    private String message;
    public BusinessException() { super(); }
    public BusinessException(String message) {
        this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
        this.message = message;
    }
}

These practices help build high‑quality, maintainable backend services.

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.

JavaException Handlingbest practicescode qualitySpringBoot
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.