在程序开发中,程序的编译与运行是两个不同的阶段,编译主要针对的是语法检测,而在程序运行时却有可能出现各种各样的错误导致程序中断执行,那么这些错误在Java中统一称为异常。
异常处理
在Java中,针对异常的处理提供3个核心关键字:try、catch、finally,利用这几个关键字就可以组成以下的异常处理格式。
try {
// 有可能出现异常的语句
}[ catch(异常类型 对象) {
// 异常处理
} catch(异常类型 对象) {
// 异常处理
} …] [finally {
// 不管是否出现异常,都执行的统一代码
}]
在格式种,已经明确表示,在try语句中捕获可能出现的异常代码。如果在try中产生了异常,则程序会自动跳转到catch语句中找到匹配的异常类型进行相应的处理。最后不管程序是否会产生异常,则肯定会执行到finally语句,finally语句就作为异常的统一出口,需要注意的是,finally块是可以省略的。
异常的基本处理流程如下图所示。

在异常处理的格式中,catch与finally都是可选的,实际上并不表示这两个语句可以同时消失,对于异常格式的组合,往往有以下几种结构形式:try…catch、try…catch…finally、try…finally。
在进行异常捕获与处理时,每一个try语句后可以设置多个catch语句,用于进行各种不同类型的异常捕获。处理多个异常时,捕获范围小的异常要放在捕获范围大的异常处理之前处理。
在Java中的完整异常处理流程如下图。

关于此流程图的说明如下。
- Java中可以处理的异常全部都是在程序运行中产生的异常,当程序运行到某行代码并且此代码执行出现异常时,会有JVM帮助用户去判断此异常的类型,并且自动进行指定类型的异常类对象实例化处理。
- 如果此时程序中并没有提供异常处理的支持,则采用JVM默认异常处理方式【图中红实线流程】,首先进行异常信息的打印;其次直接退出当前程序。
- 如果此时程序中存在异常处理,那么这个产生的异常类的实例化对象将会被try语句所捕获。
- try捕获到异常之后与其匹配的catch中的异常类型依次进行比对,如果此时与catch中的捕获异常类型相同,则认为应该使用此catch进行异常处理;如果不匹配则继续匹配后续的catch类型;如果没有任何的catch匹配成功,那么就表示该异常无法进行处理。
- 不管异常是否处理最终都要执行finally语句,但是当执行完成finally的程序代码之后会进一步判断当前的异常是否已经处理过了,如果处理过了,则继续向后执行其他代码;如果没有处理则交由JVM进行默认处理。
通过分析可以发现在整个异常处理流程中实际上操作的是一个异常类的实例化对象,这个异常类的实例化对象的类型就是异常处理的核心关键。
throws关键字
在程序执行的过程中往往会涉及不同类中方法的调用,而为了方便调用者进行异常的处理,往往会在这些方法声明时对可能产生的异常进行标记,此时就需要通过throws关键字来实现。
package cn.uihtml.demo;
class MyMath {
/**
* 定义数字除法运算,执行时可能会产生异常
* @param x 除数
* @param y 被除数
* @return 除法运算结果
* @throws Exception 计算过程中产生的异常,可以是具体异常类型,也可以简化使用Exception
*/
public static int div(int x,int y) throws Exception {
return x / y;
}
}
package cn.uihtml.demo;
class JavaDemo {
public static void main(String[] args) {
try {
System.out.println(MyMath.div(10,0))
} catch {
e.printStackTrace();
}
}
}
throw关键字
在默认情况下,所有的异常类的实例化对象都会由JVM默认实例化并且自动抛出。为了方便用户手动进行异常的抛出,JVM提供了有一个throw关键字。
package cn.uihtml.demo;
class JavaDemo {
public static void main(String[] args) {
try {
throw new Exception('手动抛出异常类实例化对象');
} catch (Exception e) {
e.printStackTrace();
}
}
}
throw 与 throws关键字的区别
【throw】是在代码块中使用,主要是手动进行异常对象的抛出。
【throws】是在方法定义中使用,表示将此方法中可能产生的异常明确告诉给调用处,由调用出进行处理。
异常处理模型
实现合理的异常处理
package cn.uihtml.demo;
class MyMath {
public static int div(int x, int y) throws Exception {
int temp = 0;
System.out.println('计算开始……');
try {
temp = x / y;
} catch (Exception e) {
throw e;
} finally {
System.out.println('计算结束……');
}
return temp;
}
}
package cn.uihtml.demo;
class JavaDemo {
public static void main(String[] args) {
try {
System.out.println(MyMath.div(10,0));
} catch (Exception e) {
e.printStackTrace();
}
}
}
本程序利用几个异常处理关键字实现了一个标准的异常处理流程,在div()方法中不管是否产生异常都会按照既定的结构执行,并且会产生的异常交由调用处来进行处理。
使用简化异常模型
package cn.uihtml.demo;
class MyMath {
public static int div(int x, int y) throws Exception {
int temp = 0;
System.out.println('计算开始……');
try {
temp = x / y;
} finally {
System.out.println('计算结束……');
}
return temp;
}
}
本程序取消了catch语句,这样一旦产生异常,在执行完finally语句之后,由于本方法没有任何的异常处理语句,所以会将异常直接通过方法声明的throws交给调用处进行处理。
RuntimeException
在Java里为了方便用户代码的编写,专门提供了一种RuntimeException类,这种异常类的最大特征在于:程序在编译的时候不会强制性地要求用户处理异常,用户可以根据自己需要进行选择性处理。但是如果没有处理异常又发生了异常,将交给JVM默认处理。也就是说,RuntimeException的子异常类可以由用户根据需要选择性进行处理。
public static int parseInt(String s) throws NumberFormatException
parseInt()方法抛出一个NumerFormatException,而这个异常类就属于RuntimeException子类。
自定义异常类
Java本身已经提供了大量的异常类,但是这些异常类在实际的工作中往往并不够使用,此时用户可以选择自定义一个异常类进行处理。
实现自定义异常类
package cn.uihtml.demo;
class BombException extends Exception {
public BombException(String msg) {
// 调用父类构造方法
super(msg);
}
}
package cn.uihtml.demo;
class Food {
public static void eat(int num) throws BombException {
if (num > 999) {
throw new BombException('东西太多,承受不了……');
} else {
System.out.println('在能力承受范围之内,可以消化掉……')
}
}
}
package cn.uihtml.demo;
class JavaDemo {
public static void main(String[] args) {
try {
Food.eat(1000);
} catch (BombException e) {
e.printStackTrace();
}
}
}
assert关键字
assert关键字主要功能是进行断言,断言是指程序执行到某行之后,其结果一定是预期的结果。
package cn.uihtml.demo;
class JavaDemo {
public static void main(String[] args) {
int x = 10;
// 中间可能会经过许多程序语句,导致变量x的内容发生改变
assert x = 100 : 'x的内容不是100';
System.out.println(x);
}
}
Java中默认是不开启断言运行的,可以使用以下语句开启断言运行。
java -ea cn.uihtml.demo.JavaDemo
原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/java/java-exception.html