第12章:异常Exception
总体内容
异常的概念
异常处理入门
- 引出为什么异常处理机制
- 异常处理的使用
异常基本介绍
异常的体系图(!继承关系图)
- 异常体系图,体现了继承和实现关系 (图片中写错了 - 应该为ctrl+alt+shift+u)
- 小结
常见的异常
常见的运行时异常(5个)
1. 空指针异常
该实例会抛出空指针异常
2. 算术异常
该实例会报抛出算术异常
int n1 = 10;
int n2 = 0;
int result = n1/n2;
3. 数组下标越界异常
该实例会抛出数组下标越界异常
4. 类型转换异常
该实例会抛出类型转换异常
5. 数值格式异常
该实例会抛出数值格式异常
常见的编译时异常
异常处理(!)
基本介绍及处理方式
两种处理机制的示意图
try-catch-finally处理机制
throws处理机制
throws异常处理机制
- 处理异常时: try-catch-finally 和 throws二选一
- 如果程序员没有显示的 处理异常,默认用的是throws,若上层模块都没有处理异常则最终抛给 jvm(输出异常信息,退出程序)
(一) tryCatch
1. 介绍
2. 注意事项
演示细节1
细节4演示的代码
public class Excise {
public static void main(String[] args) {
//1. 如果try代码块可能有多个异常
//2. 可以使用多个catch分别捕获不同的异常(只会匹配一个catch)
//2.1 匹配的顺序 根据 异常在try块中的位置 决定
//3. 要求子类异常写前面,父类异常写后面
try {
int n1 = 10;
int n2 = 0;
System.out.println(n1 / n2);//算术异常(先匹配到catch,后面的代码不再执行)
String name = null;
System.out.println(name.length());//空指针异常
} catch (NullPointerException e) {
System.out.println("空指针异常" + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("算术异常" + e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
}
}
}
演示细节5
没捕获异常就相当于直接抛出了异常,抛给jvm处理
3. 小练习
练习1
练习2
练习3
4. t-c-f 执行顺序小结
5. tryCatch最佳实践(必须输入整数)
import java.util.Scanner;
public class Excise {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = 0;
while (true) {
System.out.print("请输入一个整数:");
try {
num = Integer.parseInt(scanner.next());//这里可能抛出异常
break;//如果没有抛出异常,则循环终止
} catch (NumberFormatException e) {
System.out.println("你输入的不是一个整数");
}
}
System.out.print("输入的值是:" + num);
}
}
(二) throws
1. 介绍
解读介绍2
没有tryCatch和throws那么程序就会报错(这个例子是在编译时就报错)
2. 注意事项
对细节1和2的补充讲解:
- 编译异常必须处理
- 运行时的异常可以处理,可以不处理
自定义异常
基本概念
自定义异常的步骤及代码
public class Excise {
public static void main(String[] args) {
int age = 180;
//要求范围在18 - 120岁之间,否则抛出一个异常
if (!(age >= 18 && age <= 120)) {
//抛出一个异常(自定义异常类的对象)
//这里通过构造器,设置信息
throw new AgeException("年龄需要在18 - 120岁之间");
}
//如果没有异常,则执行这个
System.out.println("你的年龄范围正确");
}
}
//自定义一个异常
class AgeException extends RuntimeException {
public AgeException(String message) {//构造器
super(message);//调用父类构造器
}
}
throw 和 throws 的对比
小练习
本章作业
作业1(编程:抛出捕获多个异常)
分析:
- 数据格式不正确 --> NumberFomatException
- 缺少命令行参数 --> ArrayOutOfBoundsException
- 除0 --> ArithmeticException
注意
- 异常可以手动抛出
1.1 throw后面跟异常的对象
1.2 可以是自定义的异常对象,也可以是系统的异常对象
throw new ArrayIndexOutOfBoundsException("参数个数不正确");
- 异常也可以自己抛出
int a = Integer.parseInt(args[0]);
- 抛出后可以用catch捕获,也可以默认继续抛出
catch (ArrayIndexOutOfBoundsException e)
catch (NumberFormatException e)
public class Excise {
public static void main(String[] args) {
try {
//先判断输入参数的个数是否正确,若不正确,则手动抛出异常 --> 用catch捕获
if (args.length != 2) {
throw new ArrayIndexOutOfBoundsException("参数个数不正确");
}
//将两个参数转换成整数(可能会抛出NumberFormatException) --> 用catch捕获
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
//调用cal方法(可能会抛出ArithmeticException) --> 用catch捕获
int res = cal(a, b);
//如果前面三个异常都没有发生,则输出
System.out.println("result = " + res);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
} catch (NumberFormatException e) {
System.out.println("参数格式不正确,需要输入整数");
System.out.println(e.getMessage());
} catch (ArithmeticException e) {
System.out.println("出现了除数为0的情况");
}
}
//计算两数相除
public static int cal(int a, int b) {
return a / b;
}
}
作业2(判断可能抛出什么异常)
作业3(catch和finally的顺序)
这里它们两都是输出,不是return