异常概念:阻止当前方法或作用域正常运行的情况成为异常。
- Throwable 所有异常的父类
- Error 虚拟机错误和线程死锁,一旦出现程序就会崩溃
- Exception 编码、环境、用户输入等出现的异常
- RuntimeException包含四种异常: 空指针异常、数组下标越界异常、类型转换异常、算术异常
- 检查异常 其他的一些异常
Java的主要异常结构图如下:
我们所说的异常处理一般指的是Exception中的异常。
异常处理
try-catch
使用try-catch语法可以捕获多种形式的异常。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try{
System.out.println("Please enter first number:");
int one=sc.nextInt();
System.out.println("Please enter second number:");
int two=sc.nextInt();
System.out.println(one/two);
}catch (InputMismatchException e){
System.out.println("输入不匹配");
}catch(ArithmeticException e){
System.out.println("第二个数字不能为0");
}
System.out.println("Next...");
}
- 第一个catch会捕获两次输入的值不为int型的异常
- 第二个catch会捕获求商出错的异常
- 一旦出现异常会停止执行try语句块中的剩余部分,直接开始执行对应的catch语句,执行完毕后继续执行剩余代码
- 捕获不同异常主要是根据catch语句块小括号中的内容(异常类型)
- catch异常语句的类型一般设置为范围先小后大
- 可以在最后加上一个catch(exception)捕获可能遗漏的异常
finally
finally语句块放置一些try-catch语句块最终执行的函数。注:即便没有发生异常,finally语句块中的代码也会执行。
建议在finally中释放不用的资源。
throw与throws
- throw-将产生的异常抛出(动作)
- throws-声明将要抛出何种类型的异常(声明)
示例如下:
public void divide( int one,int two) throws Exception{
if(tow == 0){
throw new Exception("被除数不能为0");
}else {
System.out,println("结果为:"+one/two);
}
}
- 如果抛出了一个异常就必须捕获异常或添加throws声明,将异常抛出给更上一层的异常处理。
完整的异常分类图解
自定义异常
必须继承于意思相近的异常或即成为异常的最大父类。
public class DrunkException extends Exception{
public DrunkException(){
}
public DrunkException(String message){
}
}
异常链
如下代码中,使用throws声明一个可能抛出的异常,使用throw具体抛出一个异常,最终在这个静态方法执行后再来具体处理这个异常,这就是一个简单的异常链。
private static String getBookByName(String[] books)
throws Exception {
System.out.println("输入图书名称:");
//获取输入的图书名称
String name = console.next();
for (int i = 0; i < books.length; i++) {
if (name.equals(books[i])) {
//输入的名称与某一图书名称匹配,返回该图书
return books[i];
}
}
//若无匹配,抛出”图书不存在异常“
throw new Exception("图书不存在!");
}
最后推荐一个完整的错误处理demo。