IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 一文轻松掌握异常 -> 正文阅读

[Java知识库]一文轻松掌握异常

异常的背景

初始异常

除以 0

代码如下:

public static void main(String[] args) {
    System.out.println(10/0);
}

因为 0 不能做除数,所以会报异常:
在这里插入图片描述

数组下标越界

代码如下:

public static void main(String[] args) {
    int[] arr = {1,2,3};
    System.out.println(arr[9]);
}

因为数组的下标最大是 2 ,这里是访问下标 9 ,所以会越界。
在这里插入图片描述
上面这些都是运行时异常,我们之前还遇到过编译时异常

编译时异常

使用类克隆的时候,如果不抛出异常的话,就会报错导致出现无法完成编译:

class Person implements Cloneable{
    public int id;
}
public class Main{
    public static void main(String[] args) {
        Person person = new Person();
        Person person1 = (Person) person.clone();
    }
}

报异常如下:
在这里插入图片描述
如果重写克隆方法,并且抛出异常的话,程序就可以运行了。

class Person implements Cloneable{
    public int id;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Main{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();
    }
}

这样程序就能运行了。

异常的基本用法

捕获异常

通过 try catch 来捕获并且处理异常,代码如下:

try{
    有可能出现异常的语句 ;
}[catch (异常类型 异常对象) {
} ... ]
[finally {
    异常的出口
}]
  • try 代码块中放的是可能出现异常的代码.
  • catch 代码块中放的是出现异常后的处理行为.
  • finally 代码块中的代码用于处理善后工作, 会在最后执行.
  • 其中 catch 和 finally 都可以根据情况选择加或者不加.

异常程序的执行过程

在代码抛出异常之后,异常之后的代码就不执行了。代码如下:

public static void main(String[] args) {
    int[] arr = new int[]{1,2,3};
    System.out.println(arr[5]);
    System.out.println("哈喽!!!");
}

运行结果如下:
在这里插入图片描述
在运行到异常的代码之后,报出异常之后下面的代码就不执行了。

使用 try catch 处理异常的代码运行过程

代码如下:

public static void main(String[] args) {
    int[] arr = new int[]{1,2,3};
    try {
        System.out.println(arr[5]);
        System.out.println("haha");
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("捕捉到一个数组越界异常");
    }
    System.out.println("哈喽!!!");
}

运行结果如下:
在这里插入图片描述
通过 try 来捕捉异常,然后通过 catch 来处理异常。try 捕捉到异常之后,异常下面的代码就不执行了。然后就是 catch 来执行,catch 执行完毕之后才可以继续往下执行。当然在 catch 当中也可以添加如下代码:

e.printStackTrace();

这里就是打印异常信息栈,输出异常的位置在哪里。交给 JVM 来处理异常,JVM 来处理的话,就会直接终止程序。

出现多个异常

如果出现多个异常的话,就可以使用多个 catch 来捕捉异常。代码如下:

public static void main(String[] args) {
    int[] arr = new int[]{1,2,3};
    try {
        arr = null;
        System.out.println(arr[5]);
        System.out.println("haha");
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("捕捉到一个数组越界异常");
    } catch (NullPointerException e) {
        System.out.println("捕捉到了空指针异常");
    }
    System.out.println("哈喽!!!");
}

运行结果如下:
在这里插入图片描述
当然代码也能这样简写:

public static void main(String[] args) {
    int[] arr = new int[]{1,2,3};
    try {
        arr = null;
        System.out.println(arr[5]);
        System.out.println("haha");
    } catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
        System.out.println("捕捉到一个数组越界 或者 空指针异常");
    }
    System.out.println("哈喽!!!");
}

运行结果如下:
在这里插入图片描述

Java 的异常体系

所有的异常都来自一个 throwable :
在这里插入图片描述
如果在 IDEA 当中查看异常的父子类关系时,就有如下关系图:
在这里插入图片描述

父类 Exception

所有的异常都来自父类 Exception ,当然也可以在 catch 的时候直接写 Exception 。但是不建议这样做,因为这样就不知道是什么异常了。
注意:catch 在捕捉异常的时候,最好是先子类,再父类。这样就可以一阶一阶的处理异常。如果是先父类再子类的话,就会报错。
在这里插入图片描述

finally

finally 一般用作资源的关闭。比如关闭 Scanner :

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    try {
        System.out.println(10 / n);
    } catch (InputMismatchException e) {
        e.printStackTrace();
        System.out.println("输入有误");
    } catch (ArithmeticException e){
        e.printStackTrace();
        System.out.println("算术异常,可能 0 做了除数");
    } finally {
        scanner.close();
        System.out.println("finally 执行了");
    }
}

不论是否发生异常,finally 都会执行:
在这里插入图片描述
就算交给 JVM 处理,还是会执行 finally 代码如下:

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    try {
        System.out.println(10 / n);
    } catch (InputMismatchException e) {
        e.printStackTrace();
        System.out.println("输入有误");
    } finally {
        scanner.close();
        System.out.println("finally 执行了");
    }
}

在这里插入图片描述

try catch finally的返回值

当 try 和 finally 当中都有返回的时候,结果是什么?

public static int func3() {
    int a = 10;
    try {
        return a;
    } catch (ArithmeticException e) {
        e.printStackTrace();
    } finally {
        return 20;
    }
}
public static void main(String[] args) {
    int n = func3();
    System.out.println(n);
}

运行结果如下:
在这里插入图片描述
因为 finally 的特点是:不管抛没抛异常,finally 都会被执行。所以本来应该返回 a 的地方,就返回了 20 。所以:** 尽量避免在 finally 当中使用 return** 。

异常处理流程

  1. 程序先执行 try 中的代码
  2. 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
  3. 如果找到匹配的异常类型, 就会执行 catch 中的代码
  4. 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
  5. 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
  6. 如果上层调用者也没有处理的了异常, 就继续向上传递.
  7. 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.

自定义异常

在自定义抛出异常的时候,用 throw 来抛出异常。

public static void func4(int x) throws RuntimeException {
    if(x == 10){
        System.out.println(10 / x);
        throw new RuntimeException("x == 10");
    }
}
public static void main(String[] args) {
    try {
        func4(10);
    } catch (ArithmeticException e) {
        e.printStackTrace();
    }
}

运行结果如下:
在这里插入图片描述

利用异常实现恢复模型

使用 while 循环建立类似 ”恢复模型“ 的异常处理行为,它将不断重复,直到异常不再抛出。

public static void main13(String[] args) {
    int i = 0;
    while (i < 10) {
        try {
            if (i < 10) {
                throw new RuntimeException("x < 10");
            }
        } catch (RuntimeException e){
            e.printStackTrace();
            System.out.println("尝试处理异常");
            i++;
        }
    }
    System.out.println("异常处理结束了");
}

运行结果如下:
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 10:41:48  更:2022-01-24 10:42:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:01:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码