异常:异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。
java.lang 包中提供了一个专门用来处理异常的类:Throwable,Error 和 Exception 都是它的子类
- Error 是仅靠程序本身无法恢复的严重错误,比如 AWTError,VirtualMachineError……
- Exception 是由Java应用程序抛出和处理的非严重错误,又分为检查时异常(CheckedException)和运行时异常(RuntimeException),前者不处理将无法通过编译,后者不影响编译,但运行时可能会抛出
接下来我们着重看一下 Exception(后面的“异常”都是指 Exception)
一、常见的异常类型(包含检查时异常和运行时异常)
除了已有的异常类型,我们还可以自定义异常,只要继承 Exception 类或其子类即可
//自定义异常:年龄异常
public class AgeException extends Exception {
public AgeException(String str) {
super(str); //调用父类有参构造,参数填你想要输出的异常信息
}
}
二、异常处理机制:程序中预先设置好对付异常的处理办法,运行出现异常时,对异常进行处理,处理完毕,程序继续运行
异常处理的 5 个关键字:try、catch、 finally、throw、throws
1. try-catch-finally 结构:
try 块(try{代码块}):锁定异常捕获范围,是有可能发生异常的代码块
catch 块(catch(异常类作参数){代码块}):异常捕获,是要捕获的异常和对异常的处理
finally 块(finally{代码块}):无论如何一定会执行的操作,除非System.exit(1)或System.exit(0)
示例:
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try {
System.out.print("请输入课程代号(1~3之间的数字):");
switch (input.nextInt()) {
case 1:
System.out.println("C#编程");
break;
case 2:
System.out.println("Java全栈");
break;
case 3:
System.out.println("Web前端");
break;
default:
System.out.println("输入的数字不在1~3之间!");
break;
}
} catch (InputMismatchException e) {
System.out.println("输入的不是整数!");
e.printStackTrace();
// System.exit(1); //我这里注释了本行,所以finally块正常执行!
} finally {
//finally代码块无论如何都会执行,除非前面有System.exit(1);或System.exit(1);
System.out.println("欢迎提出建议!");
}
}
}
执行顺序:
注意:
- finally 块是否执行取决于前面的代码中有没有 System.exit(0);或 System.exit(1);
有 System.exit(0);或 System.exit(1);的,finally 块就不执行;没有就执行,return 也要先执行完 finally 块再 return - try-catch-finally 结构中 try 块是必须的;catch 块可以没有,也可以有多个;finally 块可以有,也可以没有;但 catch 块和 finally 块两者至少出现之一
- 多个 catch 块的情况下,catch 块按从小到大的顺序排列,把子类放在父类前面,一旦发生异常,进入 catch 块后按顺序逐个匹配,只执行第一个与异常类型匹配的 catch 语句
- catch 块可以自定义处理信息,也可以直接调用异常类已有的方法(异常对象常用方法如下)
2. throw 和 throws
throw:生成并抛出异常;位于方法体内;可作为单独语句使用;只能抛出一个异常
throws:声明某个方法可能抛出的各种异常;位于方法的参数列表与方法体之间;不能单独使用;可以跟多个异常,多个异常之间用逗号隔开(注意:main()方法声明的异常由Java虚拟机处理)
以上面自定义的年龄异常(AgeException)为例,手动抛出异常示例:
public class Person {
private int age;
//抛出多个异常
public void setAge(int age) throws Exception {
if(age >= 1 && age <= 100) {
this.age = age;
}else {
//生成并抛出异常
throw new AgeException("年龄必须在1到100之间");
}
}
public static void main(String[] args) throws Exception {
Person a = new Person();
a.setAge(300);
}
}
当一个方法体中抛出了异常,该方法的调用者可以选择通过 try-catch-finally 结构处理异常,也可以继续向外抛出异常,当异常抛至程序入口,main()方法中仍未解决的异常将抛由Java虚拟机处理
3. 异常处理原则
- 注意异常处理与性能
- 异常只能用于非正常情况
- 不要将过于庞大的代码块放在try中
- 在catch中指定具体的异常类型
- 需要对捕获的异常做处理