Java exception handling
Exception handling is used to describe, pass, and handle exceptions that occur during program execution. Reasonable use of exceptions can help locate errors and take remedial actions in recoverable scenarios.
Exception mechanisms cannot replace normal business judgment, nor can they ensure that the program will continue to run under any circumstances.
1. Abnormal system

All objects that can be thrown in Java inherit from Throwable. It is mainly divided into two categories: Error and Exception.
Error
Error typically represents a serious problem in the JVM or runtime environment, such as OutOfMemoryError. Such problems are often not recoverable by ordinary business code, so they are generally not captured in business code and then executed.
Exception
Exception represents the exception that the program may handle, which can continue to be divided into runtime exceptions and checked exceptions.
runtime exception
RuntimeException and its subclasses are run-time exceptions. The compiler does not mandate capture or declaration, and common types include:
NullPointerExceptionArrayIndexOutOfBoundsExceptionClassCastExceptionArithmeticExceptionIllegalArgumentException
Runtime exceptions are usually related to illegal parameters, incorrect object state, or program logic flaws, and should be avoided first by checking and correcting code, rather than relying on a large number of catch to hide problems.
Abnormal inspected
Exception, other than RuntimeException and its subclasses, is usually an exception under inspection, such as IOException.
The compiler requires the program to use one of the following methods:
- Capture using
try-catch. - Use
throwsto declare and continue to spread to callers.
“Checking” occurs during the compilation stage, but exception objects may occur only when the program runs to the relevant statement.
2. Use try-catch-finally
basic syntax
try {
// 可能出现异常的代码
} catch (SpecificException e) {
// 处理特定异常
} catch (Exception e) {
// 处理其他异常
} finally {
// 通常用于释放资源或执行收尾操作
}Implementation rules are as follows:
-
When no exception is thrown in
try, the correspondingcatchwill not be executed. -
When an exception is thrown in
try, the JVM looks from top to bottom for the first type matchingcatch. -
More specific subclass exceptions must be written before broader parent exceptions, otherwise subsequent branches cannot be reached.
-
finallyis usually executed, except in special circumstances such as forced termination of the JVM, process crash, orSystem.exit()is executed.
example
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExceptionDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
int i = scanner.nextInt();
int j = scanner.nextInt();
int result = i / j;
System.out.println("相除结果:" + result);
int[] arr = new int[5];
System.out.println(arr[i]);
System.out.println("计算完毕");
} catch (ArithmeticException e) {
System.out.println("除数不能为零");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组索引越界");
} catch (InputMismatchException e) {
System.out.println("请输入整数");
} catch (Exception e) {
System.out.println("程序出现其他异常");
e.printStackTrace();
} finally {
scanner.close();
System.out.println("输入资源已关闭");
}
System.out.println("程序继续执行");
}
}In actual projects, exceptions should not be ignored after just outputting fuzzy prompts. It is often necessary to log the exception stack, return explicit error messages, or convert exceptions to types that the current business layer can understand.
3. Use try-with-resources
try-with-resources has been available since Java 7 and is used to automatically shut down resources. Resource objects must implement the AutoCloseable interface.
Traditional writing
import java.io.FileInputStream;
import java.io.IOException;
public class ResourceDemo {
public static void main(String[] args) {
FileInputStream input = null;
try {
input = new FileInputStream("d:/a.txt");
System.out.println(input.read());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}A null value judgment must be made before closing, otherwise when resource creation fails, NullPointerException may appear again in finally.
Recommended writing
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFileDemo {
public static void main(String[] args) {
try (
FileInputStream input = new FileInputStream("d:/a.txt");
FileOutputStream output = new FileOutputStream("d:/b.txt")
) {
input.transferTo(output);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("程序继续执行");
}
}Notes:
tryResources in parentheses must implementAutoCloseable.- When multiple resources are declared, the order of closure is reversed from the order of declaration.
- Resource variables cannot be reassigned in block
try. - Starting with Java 9, resource variables that are externally declared and meet the “practically immutable” condition can also be used.
- If the business code and
close()throw exceptions at the same time, the exceptions generated when the resource is closed will be saved as suppressed exceptions and can be obtained throughgetSuppressed().
4. Exception declaration using throws
throws is written after the method or constructor declaration, indicating that the current method does not catch the exception here, but allows the exception to continue to propagate to the caller.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class FileService {
public FileInputStream openFile(String path) throws FileNotFoundException {
return new FileInputStream(path);
}
}throws itself does not handle exceptions. The caller still needs to catch the exception or continue to declare upward using throws.
Method can declare multiple exceptions:
public void execute() throws FirstException, SecondException {
// 方法体
}
If a parent exception is declared, it is usually not necessary to declare its child exception repeatedly.
5. Use throw to throw exceptions
throw is used to throw a specific exception object in the method body.
public void copy(String sourcePath, String targetPath) {
if (sourcePath == null || targetPath == null) {
throw new IllegalArgumentException("源路径和目标路径不能为空");
}
// 执行复制操作
}
After the program executes to throw, the current code path will be interrupted immediately, and control will be handed over to the calling layer that can handle the exception.
Differences between throw and throws
| Keywords | Usage position | Role |
|---|---|---|
throw | method body | throws a specific exception object |
throws | declares exception types that may be propagated to callers after method or constructor declaration |
6. Custom exceptions
Business exceptions can be defined when the exception types provided by the JDK cannot clearly express the business meaning.
Custom checked exceptions
public class InvalidEmailAddressException extends Exception {
public InvalidEmailAddressException(String message) {
super(message);
}
}
public class EmailManager {
public void sendEmail(
String recipient,
String title,
String content
) throws InvalidEmailAddressException {
if (recipient == null || recipient.isBlank()) {
throw new InvalidEmailAddressException("收件人地址不能为空");
}
System.out.println("发送邮件成功");
}
}After inheriting Exception, the caller must catch or declare the exception.
Custom runtime exceptions
If exceptions indicate incorrect parameters, unsatisfactory business rules, and you don’t want to force explicit capture of each layer of code, you can also inherit RuntimeException:
public class InvalidEmailAddressException extends RuntimeException {
public InvalidEmailAddressException(String message) {
super(message);
}
}
The choice between a checked exception or a runtime exception should be determined based on whether the caller can recover, project exception handling specifications, and framework conventions.
7. Suggestions for handling exceptions
- Capture exceptions that you can actually handle, and don’t ignore them meaningfully.
- Prioritize capturing specific exceptions and avoid directly using overly broad
Exception. - Keep the original exception as
causeand do not lose the root cause of the problem. - Do not use exceptions for ordinary process control.
- Resources are managed with
try-with-resourcesfirst. - Returns stable error information externally, and records the complete exception stack and necessary context internally.
If you enjoyed this, leave a comment~