Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5Mobile wallpaper 6Mobile wallpaper 7Mobile wallpaper 8
1340 字
7 分钟
Java:异常及其处理
2026-03-23

文章目录#

一、 异常的体系结构#

异常指的是程序中的不正确行为,比如之前遇到的数组越界,空指针异常等。

通常说的异常是Java中的 Exception ,与之并列的是 Error ,指的是JVM无法处理的严重问题,比如JVM内部问题、资源耗尽等,代表是 StackOverflowError 和 OutOfMemoryError。

ExceptionError 都是异常体系的顶层类 Throwable 的子类,Exception 又分为编译时异常(受查异常)和运行时异常(非受查异常),受查异常强制要求编译器进行处理,否则无法编译。

再往下分类出更加具体的各种异常,比如上面提到的数组越界异常。 详见下图: 异常的体系结构

二、异常的处理#

throw 关键词#

throw 用于人为抛出异常,例如:

throw new ArrayIndexOutOfBoundsException("人为抛出数组越界异常");

得到的结果为:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 人为抛出数组越界异常
at TestDemo.main(TestDemo.java:11)

throws 关键词#

throws 关键词用于声明该方法可能会产生异常,需要进行处理,相当于是把处理异常的部分交给了方法的调用者。

throws 关键词在定义方法的时候使用,如果需要声明多个异常则用逗号隔开,比如以下实例:

public static void ExceptionProducer() throws ArithmeticException, AbstractMethodError {
throw new ArithmeticException("1111");
}

try-catch-finally#

产生异常,抛出异常,现在终于到了处理异常的环节了。

trycatchfinal分别对应着处理异常的“运行”、“处理”和“收尾”三个阶段。 例如以下实例:

try {
System.out.println("抛出异常");
throw new ArrayIndexOutOfBoundsException("人为异常");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("已处理数组越界异常");
} finally {
System.out.println("after");
}

结果为:

抛出异常
已处理数组越界异常
after

接下来我们一个一个来讲:

try#

try 用于运行可能会出现异常的代码,并且将产生的异常抛出。

需要注意的是,try 内部运行的代码只会到产生异常的部分,如果已经产生了异常,那后面的代码都不会运行,比如以下实例:

try {
System.out.println("抛出异常");
throw new ArrayIndexOutOfBoundsException("人为异常");
System.out.println("111");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("已处理数组越界异常");
} finally {
System.out.println("after");
}

编译器会警告说 System.out.println("111"); 是无法执行的语句。

这对于 throw 关键词也是一样的,在下面的实例中也会被警告说这是无法执行的语句

throw new ArrayIndexOutOfBoundsException("人为抛出数组越界异常");
throw new ArithmeticException("111");

catch#

catch 用于捕获 try 产生的异常,形式是 catch(异常类型 e) {语句},如果 catch 中的异常类型和抛出的异常类型一样,则会捕获异常类型并运行对应语句。

异常的捕获存在父子类的关系,也就是说抛出的子类的异常可以被父类的 catch 捕获。同时因为一个异常只会被一个 catch 语句捕获,因此如果在捕获父类异常的时候想要单独捕获子类的异常的时候,需要把子类的异常写在前面,就像以下示例:

try {
System.out.println("抛出异常");
throw new ArrayIndexOutOfBoundsException("人为异常");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("已处理数组越界异常");
} catch(Exception e) {
System.out.println("111");
} finally {
System.out.println("after");
}

如果中间两个 catch 写反了就会显示:已捕获到异常错误java.lang.ArrayIndexOutOfBoundsException。

如果 try 运行在不同的情形下可能会产生了多个异常,可以用多个 catch 进行捕获,并进行处理,例如以下实例:

int[] array = {1};
try {
//array = null;
int a = array[110];
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("已处理数组越界异常");
} catch(NullPointerException e) {
System.out.println("已处理空指针异常");
} finally {
System.out.println("after");
}

现在抛出的结果是数组越界异常,如果去掉注释就是空指针异常。 如果这两个异常的处理方式相同,还可以采取并列的方式:

int[] array = {1};
try {
array = null;
int a = array[110];
} catch(ArrayIndexOutOfBoundsException | NullPointerException e) {
System.out.println("已处理异常");
} finally {
System.out.println("after");
}

finally#

用于处理异常的收尾阶段,具有必然运行的特点,可以用于运行无论程序是否发生异常都需要执行的代码,比如回收资源。

public static int getData(){
Scanner sc = null;
try{
sc = new Scanner(System.in);
int data = sc.nextInt();
return data;
}catch (InputMismatchException e){
e.printStackTrace();
}finally {
System.out.println("finally中代码");
}
System.out.println("try-catch-finally之后代码");
if(null != sc){
sc.close();
}
return 0;
}
public static void main(String[] args) {
int data = getData();
System.out.println(data);
}

(懒得调缩进了将就着看一下()

我们会发现finally中代码和try-catch-finally后的代码是有运行的差别的,finally之后的代码可能无法执行,如果资源回收在try-catch-finally后执行的话可能会被跳过。

因此finally的存在是有必要的。

三、自定义异常#

在实际使用中,现有的异常可能不完全符合我们的需求,这个时候我们就可以自定义一个异常类型。实例如下:

public class NameException extends Exception{
public NameException(String message) {
super(message);
}
}

想要抛出该异常可以:

if (name != userName) {
throw new NameException("用户名错误");
}

继承自 Exception 的异常默认为受查异常。 继承自 RunException 的异常默认为运行时异常。

Java:异常及其处理
https://blog.csdn.net/2501_93882415/article/details/159390888?spm=1001.2014.3001.5502
作者
Mem0rin
发布于
2026-03-23
许可协议
MIT

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00