4.6java异常处理

发布于:2025-05-10 ⋅ 阅读:(15) ⋅ 点赞:(0)

 在 Java 中,异常(Exception)是指在程序执行过程中发生的不正常事件,它会中断程序的正常流程。Java 提供了一套完整的异常处理机制,帮助开发者更好地处理程序运行时出现的各种错误,增强程序的健壮性。

异常的分类

在 Java 中,异常类都继承自 java.lang.Throwable 类,Throwable 有两个直接子类:Error 和 Exception

1. Error

Error 类表示系统级的错误和资源耗尽错误,通常是由 JVM 或底层系统产生的,程序无法处理这些错误,也不应该尝试去捕获它们。例如,OutOfMemoryError 表示内存不足,StackOverflowError 表示栈溢出。

2. Exception

Exception 类表示程序可以捕获和处理的异常,它又可以分为两类:

  • 受检查异常(Checked Exception):这类异常在编译时会被编译器检查,要求开发者必须进行处理(捕获或声明抛出)。常见的受检查异常包括 IOExceptionSQLException 等。
  • 非受检查异常(Unchecked Exception):也称为运行时异常(Runtime Exception),这类异常在编译时不会被编译器检查,通常是由程序逻辑错误引起的。常见的运行时异常包括 NullPointerExceptionArrayIndexOutOfBoundsExceptionArithmeticException 等。

层次结构图​​:

Throwable
├── Error
└── Exception
    ├── RuntimeException(运行时异常)
    └── 其他受检异常(如 IOException)

异常处理机制

Java 提供了 trycatchfinally 和 throwthrows 等关键字来实现异常处理。

1. try-catch 块

try-catch 块用于捕获和处理异常。try 块中包含可能会抛出异常的代码,catch 块用于捕获并处理相应的异常。

public class TryCatchExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // 会抛出 ArithmeticException
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("捕获到算术异常: " + e.getMessage());
        }
    }
}

多重捕获(Multi-catch)​
Java 7+ 支持在一个 catch 块中捕获多个异常类型:

catch (IOException | SQLException e) { ... }

2. try-catch-finally 块

finally 块是可选的,无论 try 块中是否抛出异常,finally 块中的代码都会被执行。通常用于释放资源,如关闭文件、数据库连接等。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TryCatchFinallyExample {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("test.txt");
            // 读取文件的代码
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + e.getMessage());
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                System.out.println("关闭文件时出错: " + e.getMessage());
            }
        }
    }
}
  • try-with-resources 自动关闭资源(Java 7+):
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    // 自动关闭流
}

3. throws 关键字

throws 关键字用于在方法声明中声明该方法可能会抛出的异常,调用该方法的代码必须处理这些异常。

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ThrowsExample {
    public static void readFile() throws FileNotFoundException {
        FileInputStream fis = new FileInputStream("test.txt");
        // 读取文件的代码
    }

    public static void main(String[] args) {
        try {
            readFile();
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + e.getMessage());
        }
    }
}
4. throw 关键字

throw 关键字用于手动抛出一个异常对象。

public class ThrowExample {
    public static void checkAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
        System.out.println("年龄合法: " + age);
    }

    public static void main(String[] args) {
        try {
            checkAge(-5);
        } catch (IllegalArgumentException e) {
            System.out.println("捕获到异常: " + e.getMessage());
        }
    }
}

自定义异常

在 Java 中,你可以通过继承 Exception 或 RuntimeException 类来创建自定义异常。

// 自定义受检查异常
class MyCheckedException extends Exception {
    public MyCheckedException(String message) {
        super(message);
    }
}

// 自定义运行时异常
class MyRuntimeException extends RuntimeException {
    public MyRuntimeException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {
    public static void main(String[] args) {
        try {
            throw new MyCheckedException("这是一个自定义受检查异常");
        } catch (MyCheckedException e) {
            System.out.println("捕获到自定义受检查异常: " + e.getMessage());
        }

        try {
            throw new MyRuntimeException("这是一个自定义运行时异常");
        } catch (MyRuntimeException e) {
            System.out.println("捕获到自定义运行时异常: " + e.getMessage());
        }
    }
}

异常处理的最佳实践

  • 捕获特定的异常:尽量捕获特定的异常,而不是捕获通用的 Exception 类,这样可以更精确地处理不同类型的异常。
  • 避免空的 catch 块:空的 catch 块会隐藏异常,导致调试困难,应该在 catch 块中记录异常信息或进行相应的处理。
  • 使用 finally 块释放资源:对于需要手动释放的资源,如文件、数据库连接等,应该在 finally 块中进行释放。
  • 合理使用 throws 和 throw:在方法中,如果无法处理某些异常,可以使用 throws 关键字将异常抛给调用者;如果需要手动抛出异常,可以使用 throw 关键字。

网站公告

今日签到

点亮在社区的每一天
去签到