JAVA异常的处理(try catch finally)

概述

Java异常处理的五个关键字:try、catch、finally(不是final)、throw、throws

如果异常出现,会立刻终止程序,如下代码:

Scanner scanner = new Scanner(System.in);
System.out.println("请输入被除数:");
int a=scanner.nextInt();
System.out.println("请输入除数:");
int b=scanner.nextInt();
System.out.println(a/b);

当输入 非数字时,或者 除数是 0 时,就会抛出异常,并终止运行。
这种程序的用户体验很差,用户更希望的是,不能正确执行时,给出提示,并继续运行

所以我们需要处理异常

捕获异常try…catch

Java中对异常有针对性的捕获,可以对出现的异常进行指定方式的处理。

语法

try{
     可能出现异常的代码
}catch(异常类型  e){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}
其他代码
  • try代码块:该代码块中编写可能产生异常的代码。
  • catch代码块:用来捕获异常,并对异常进行处理。

没发生异常时:
当try代码块,没发生异常时,不执行 catch代码块,直接执行其他代码

发生异常时:
当try代码块,发生异常时,中断try代码块,执行 catch代码块,然后根据情况 决定 是否执行其他代码

例子:

Scanner scanner = new Scanner(System.in);
System.out.println("请输入除数:");
int a=0;
try {
     a= scanner.nextInt();
}catch (Exception e){
    System.out.println("错误,只能输入数字");
    return;
}

System.out.println("请输入被除数:");
int b=0;
try {
    b = scanner.nextInt();
}catch (Exception e){
    System.out.println("错误,只能输入数字");
    return;
}
try {
    System.out.println(a / b);
}catch (Exception e){
    System.out.println("错误,除数不能是0");
}

注意:

  • 运行时异常可以不处理,但抛出异常后,仍然会中断程序

捕获多个异常

  1. 多个异常分别处理。
  2. 多个异常一次捕获,多次处理。
  3. 多个异常一次捕获一次处理。

一般我们是使用一次捕获多次处理方式,格式如下:

try{
    可能出现异常的代码
}catch(异常类型A  e){
    处理异常的代码
    //记录日志/打印异常信息/继续抛出异常
}catch(异常类型B  e){
    处理异常的代码
    //记录日志/打印异常信息/继续抛出异常
}

注意:

  • 多个catch中的异常不能相同
  • 若catch中的多个异常之间有 父子关系 的异常,子类异常要在上面的catch处理,父类异常在下面的catch处理,否则子类异常的 catch 扑捉不到异常

finally 代码块

有时,一些特定的代码 无论异常是否发生,都需要执行。另外,因为异常会引发 程序跳转,导致有些语句 执行不到。

finally 就是解决这个问题的,在 finally代码块 中的代码 一定会执行。

应用场景

当我们在try语句块中打开了一些物理资源(磁盘文件/网络连接/数据库连接等),我们都得在 使用完之后,及时 关闭。

语法

try{

}catch(){

}finally{

}

或者

try{

}finally{

}

注意: finally代码块不能单独使用。

例子:
比如在之后学习的IO流中,打开文件,最后程序不管结果如何,都需要把这个资源关闭掉。

伪代码:

public class TryCatchDemo4 {
    public static void main(String[] args) {
        try {
            read("a.txt");
        } catch (FileNotFoundException e) {
            //抓取到的是编译期异常  抛出去的是运行期 
            throw new RuntimeException(e);
        } finally {
            System.out.println("不管程序怎样,这里都将会被执行。");
        }
        System.out.println("over");
    }
    /*
     *
     * 我们 当前的这个方法中 有异常  有编译期异常
     */
    public static void read(String path) throws FileNotFoundException {
        if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
            // 我假设  如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常  throw
            throw new FileNotFoundException("文件不存在");
        }
    }
}

注意:当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行。

finally 代码块中有return

如果finally有return语句,永远返回finally中的结果,避免该情况

public static int test(){
    int r=0;
    try{
        r=1/2;
    }finally {
        return -1;
    }
    //报错,因为永远都会执行 finally 代码块中的return
    //所以此return语句永远不会执行到
    return r;
}

try 和 catch、finally关系

  • try 与 catch 连用
  • try 与 finally 连用
  • try 与 catch 和 finally 连用

注意:try、catch、finally不能单独出现,否则报错