[Java异常]异常
Throwable 是 Java 语言中所有错误与异常的超类。
Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。
Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。
Error(错误)
Error 类及其子类:程序中无法处理的错误,表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时 JVM 出现问题。
通常有 VirtualMachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等。比如 OutOfMemoryError:内存不足错误;StackOverflowError:栈溢出错误。
此类错误发生时,JVM 将终止线程。这些错误是不受检异常,非代码性错误。因此,当此类错误发生时,应用程序不应该去处理此类错误。按照Java惯例,我们是不应该实现任何新的Error子类的!
Exception(异常)
程序本身可以捕获并且可以处理的异常。Exception 这种异常又分为两类:运行时异常和编译时异常。
运行时异常都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常)是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)
可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
不可查异常(编译器不要求强制处置的异常)包括运行时异常(RuntimeException与其子类)和错误(Error)。
在Java中,错误(Error)和异常(Exception)都是继承自 Throwable
类的子类,但它们在性质和处理上有着明显的区别。
Error(错误)#
Error
类及其子类表示系统级的异常,通常是由于JVM本身的问题引起的。这些错误通常表示更严重的问题,程序一般不应尝试捕获和处理这些错误。
常见的错误类型:#
OutOfMemoryError
: 当JVM没有足够的内存来分配给对象时抛出。StackOverflowError
: 当JVM的栈内存被耗尽,通常是由于递归方法调用过多导致的。VirtualMachineError
: 当JVM出现某些内部错误或资源耗尽时抛出。
特点:#
- 这些错误通常是不可恢复的。
- 通常不需要(也不建议)程序员去捕获和处理它们。
Exception(异常)#
Exception
类及其子类表示程序本身可以处理的情况。异常是可以通过捕获和处理来恢复的。
常见的异常类型:#
IOException
: 输入/输出操作失败或中断时抛出。SQLException
: 数据库操作失败时抛出。NullPointerException
: 尝试访问null对象的方法或属性时抛出。IndexOutOfBoundsException
: 当索引超出范围时抛出。
特点:#
- 分为受检异常(Checked Exception)和非受检异常(Unchecked Exception)。
- 可以使用try-catch块捕获和处理。
- 程序应合理地捕获和处理异常,以确保程序的健壮性和用户体验。
受检异常(Checked Exception)#
受检异常是编译时异常,必须在方法声明中进行处理(使用throws
关键字)或者在方法内部捕获(使用try-catch
块)。这些异常通常是程序本身之外的条件导致的,需要程序员进行预防和处理。
常见的受检异常:#
IOException
SQLException
ClassNotFoundException
非受检异常(Unchecked Exception)#
非受检异常是运行时异常,程序不强制要求处理。这些异常通常是程序中的错误导致的,比如逻辑错误或编程错误。
常见的非受检异常:#
NullPointerException
ArrayIndexOutOfBoundsException
IllegalArgumentException
代码示例#
Error 示例:#
public class ErrorExample {
public static void main(String[] args) {
try {
causeStackOverflow();
} catch (StackOverflowError e) {
System.err.println("Caught StackOverflowError: " + e.getMessage());
}
}
public static void causeStackOverflow() {
causeStackOverflow(); // 无限递归调用
}
}
Exception 示例:#
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ExceptionExample {
public static void main(String[] args) {
try {
readFile("nonexistentfile.txt");
} catch (FileNotFoundException e) {
System.err.println("Caught FileNotFoundException: " + e.getMessage());
}
}
public static void readFile(String fileName) throws FileNotFoundException {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
scanner.close();
}
}
总结#
- 错误(Error)表示系统级问题,通常不可恢复,不建议捕获和处理。
- 异常(Exception)表示程序本身可以处理的情况,分为受检异常(需要处理)和非受检异常(可以选择处理)。
- 处理异常是编写健壮的Java应用程序的重要部分,而错误一般由JVM处理。
throw和throws的区别#
-
throw 在
方法体
内使用,throws 在方法声明
上使用; -
throw 后面接的是
异常对象
,只能接一个。throws 后面接的是异常类型
,可以接多个,多个异常类型用逗号隔开; -
throw 是在方法中出现不正确情况时,手动来抛出异常,结束方法的,执行了 throw 语句一定会出现异常。而 throws 是用来声明当前方法有可能会出现某种异常的,如果出现了相应的异常,将由调用者来处理,声明了异常不一定会出现异常。
其中,throw 是用在某个方法的方法体内的,当我们认定某种情况不合理时,就可以创建异常对象,封装好异常信息,然后通过 throw 来抛出异常并终止该方法。
public class Student {
// 性别
private String gender;
public String getGender() {
return gender;
}
public void setGender(String gender) {
if (!("男".equals(gender) || "女".equals(gender))) {
throw new IllegalArgumentException("非法性别:" + gender);
}
this.gender = gender;
}
}
而 throws 是用在某个方法的方法声明上的,表示当前方法如果抛出了某些异常,将由调用者来进行异常处理。这种方式也可以让调用者知晓该对哪些异常进行处理。throws 声明的异常不一定会出现,只是一种可能。
public class FileInputStream extends InputStream {
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?