目录
一.什么是异常
定义:
在程序运行过程中出现的错误,称为异常
。异常就是程序运行过程中出现了不正常现象导致程序的中断。在Java中,把各种异常现象进行了抽象形成了异常类。
二.异常的分类
三.异常的分类
异常主要分为:错误、一般性异常(受控异常)、运行时异常(非受控异常)
错误
如果应用程序出现了Error,那么将无法恢复,只能重新启动应用程序,最典型的Error的异常是:OutOfMemoryError
受控异常
这种异常属于一般性异常,出现了这种异常必须显示的处理,不显示处理java程序将无法编译通过。编译器强制普通异常必须try…catch处理,或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常。
非受控异常
非受控异常也即是运行时异常(RuntimeException),这种系统异常可以处理也可以不处理,所以编译器不强制用try…catch处理或用throws声明,所以系统异常也称为unchecked异常。
此种异常可以不用显示的处理,例如被0除异常,java没有要求我们一定要处理, 当出现这种异常时,肯定是程序员的问题,也就是说,健壮的程序一般不会出现这种系统异常。
四.异常的处理方式
运行时异常(系统异常)
不需要预处理,通过规范的代码可以避免产生这种异常受检异常(编译时异常)
必须预处理,否则编译报错,有两种预处理方式 :
- 捕获处理
- 抛出处理
4.1 异常的捕获处理
4.1.1 try、catch和finally
第一种情况 :try块中所有语句正常执行完毕,不会发生异常,那么catch块中的所有语句都将会被忽略
public void method(){
try {
// 代码段(此处不会产生异常)
} catch (异常类型 ex) {
// 对异常进行处理的代码段
}
// 代码段
}
第二种情况 :try语句块在执行中遇到异常,那么在try块中其余剩下的代码都将被忽略,系统会自动生成相应的异常对象,如果这个异常对象与catch中声明的异常类型相匹配,则相应的catch块将会被执行
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段4
}
// 代码段5
}
第三种情况 :try语句块在执行中遇到异常,如果这个异常对象与catch中声明的异常类型不匹配,程序会中断。
public void method(){
try {
// 代码段 1
// 产生异常的代码段2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段4
}
// 代码段5
}
- try中包含了可能产生异常的代码
- try后面是catch,catch可以有一个或多个,catch中是需要捕获的异常
- 当try中的代码出现异常时,出现异常下面的代码不会执行,马上会跳转到相应的catch语句块中,如果没有异常不会跳转到catch中
- finally表示,不管是出现异常,还是没有出现异常,finally里的代码都执行,finally和catch可以分开使用,但finally必须和try一块使用,如下格式使用finally也是正确的
try {
} catch (异常类型 e) {
} catch (异常类型 e) {
} finally {
}
异常的截获一般按照由小到大的顺序,也就是先截获子异常,再截获父异常。
String[] courses = {"C语言程序设计","Java程序设计","SQL基础"};
System.out.println("请输入课程代号(1~3之间的数字):");
int choose = 0;
try {
//输入选择
choose = sc.nextInt();
//输出选择信息
System.out.println(courses[choose-1]);
//捕捉输入类型不匹配异常
}catch (InputMismatchException e){
System.err.println("你输入的非数值");
//捕捉数组越界异常
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("你输入的不是(1-3的数字)");
//捕捉总异常
}catch(Exception exception){
System.out.println("输入有误!!");
}finally {
System.out.println("欢迎提出建议!");
}
五.常见的异常类
异常类 | 说明 |
---|---|
ClassCastException | 类型转换异常 |
ArrayIndexOutOfBoundsException | 数组越界异常 |
NegativeArraySizeException | 指定数组维数为负值异常 |
ArithmeticException | 算数异常 |
InternalException | Java系统内部异常 |
NullPointerException | 空指针异常 |
IllegalAccessException | 类定义不明确所产生的异常 |
IOException | 一般情况下不能完成I/O操作产生的异常 |
EOFException | 打开文件没有数据可以读取的异常 |
FileNotFoundException | 在文件系统中找不到文件路径或文件名称时的异常 |
ClassNotFoundException | 找不到类或接口所产生的异常 |
CloneNotSupportedException | 使用对象的clone方法但无法执行Cloneable所产生的异常 |
六.throw
throw
关键字,用于主动地抛出异常;- 正常情况下,当年龄大于100的时候,程序会主动抛出AgeException(自定义异常);
- 当时如果我们想要除数为1的时候也抛出AgeException异常,就可以使用
throw
关键字主动地抛出异常。
throw new AgeException("年龄输入错误!!");
语法也非常简单,throw 关键字后跟上 new 关键字,以及异常的类型还有参数即可。
public void setAge(int age) throws AgeException {
//判断参值是否在范围之内
if (0 <= age && age <= 100){
this.age = age;
}else {
//默认值
this.age = 60;
//抛出异常
throw new AgeException("年龄输入错误!!");
}
}
运行结果,如果年龄大于100就出抛出异常
七.throws
throws
关键字的作用就和throw
完全不同。用于在类的方法中抛出异常,当在方法中不想用try-catch括住异常的时候,可以通过在方法签名上声明throws
向上抛出异常。- 假设现在可能会出现 AgeException异常,也可能会出现
ArithmeticException
。这种情况下,可以使用try-catch
来处理。 try-catch
与throws
的使用应该由调用函数来确定的,如果异常需要让调用者知道,并由调用者捕获处理的话,就应该向上抛出。如果调用者不需要捕获,则直接try-catch
显式抛出异常。
public static void main(String args[]){
try {
foot();
} catch (AgeException e) {
// 算术异常
} catch (ArithmeticException e) {
// 空指针异常
}
}
public static void foot() throws AgeException , ArithmeticException {
// 方法签名上声明异常
}
八.throw和throws的区别
throws
关键字用于声明异常(向上抛出异常,交给其调用方法来处理),他的作用和try-catch相似;而throw
关键字用于显式抛出异常。throws
关键字后面跟的是异常的名字;而throw
关键字后面跟的是异常的对象。
throw new AgeException("年龄输入错误!!");
throws
关键字出现在方法的签名上的后面,而throw
关键字出现在方法体里。throws
关键字在声明异常的时候可以跟多个异常,只需要用逗号隔开即可;而throw
关键字每次只能抛出一个异常。