五分钟”手撕“异常

news2024/11/18 3:41:11

目录

一、什么是异常

二、异常的体系和分类

三、异常的处理

1.抛出异常

2.异常的捕获

 异常声明throws:

try-catch处理

四、finally 

finally一定会被执行吗? 

五、throw和throws区别

六、异常处理的流程

七、自定义异常


一、什么是异常

顾名思义:就是不正常。比如:

当一个正在运作的机器突然卡了,或者不动了,我们称为异常;

当一个健康的人突然生病了,身体开始不舒服,我们称为异常。

所以:在Java中,将程序执行过程中发生的不正常行为称为异常

二、异常的体系和分类

异常种类繁多,为了对不同异常或者错误进行很好的分类管理,Java内部维护了一个异常的体系结构,Java中的异常是用类来描述的,有各种各样的异常类: 、

 从上图可以看到的体系

1. Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception

2. Error指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowError和OutOfMemoryError,一旦发生回力乏术

3. Exception异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说 的异常就是Exception。

 

 从上图可以看到的分类

但我们平常说的异常是Exception,它可以分为编译时异常 or 受查异常(check Excepton)和运行时异常 or 非受查异常(uncheck Exception) 。

1.运行时异常,也叫非受查异常,它是用RuntimeException这个类继承的,就是在我点击run运行的时候,它才会报错 

public static void main(String[] args) {
        //算术异常
        System.out.println(10/0);
        //数组越界异常
        int[] array = new int[10];
        System.out.println(array[10]);
        //空指针异常
        int[] array1 = null;
        System.out.println(array1.length);
    }

2.编译时异常,也叫受查时异常,我之前博客也有写过克隆接口,就是在写代码的时候直接报红线,你都编译都不通过: 

class Person implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) {
        //编译时异常 也叫 受查异常
        Person person = new Person();
        Person person1 = (Person) person.clone();
    }
}

当然,大家要注意:语法错误不算异常!!!! 比如:下图,少了个分号(中文分号,变量名重复,关键字拼写错误....等等都只算语法错误,并不是异常)

  

三、异常的处理

既然我们知道异常影响代码的工作,那我们怎么处理呢?

在Java中,异常处理主要的5个关键字:throw、try、catch、final、throws。

1.抛出异常

 在Java中,可以借助throw关键字抛出一个指定的异常对象,将错误信息告知给调用者

public static void getElement(int[] arr, int index)  {
        if (arr == null) {
            throw new NullPointerException("数组为空");
        }if(index<0||index>=arr.length){
            throw new ArrayIndexOutOfBoundsException("数组越界");
        }
}
public class Test{
    public static void main(String[] args) {
        int[] array = {1,2,3};
        getElement(array, 3);
        System.out.println("你好");
    }
}

【注意事项】:

1. throw必须写在方法体内部。

2. 抛出的对象必须是Exception 或者 Exception 的子类对象。

3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,代码不报错不划红线,则可以不用处理,直接交给JVM来处理

4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译。

5. 异常一旦抛出,其后的代码就不会执行 。

2.异常的捕获

 异常的捕获,也就是异常的具体处理方式,主要有两种:异常声明throws 以及 try-catch捕获处理。

 异常声明throws:

public class Config {
    File file;
    public void OpenFile(String name)throws FileNotFoundException{
        if(name.equals("abc")){
            throw new FileNotFoundException("文件名出错");
        }
    }
}

也就是在方法的后面写上:throws+xxxException 。

FileNotFoundException : 编译时异常,

表明文件不存在 此处不处理,也没有能力处理,应该将错误信息报告给调用者,让调用者检查文件名字是否给错误了。

(如果在main方法也不想画红线,在main方法后面也throws就好了,但是都没有处理这个异常,这时候就会交给JVM处理,JVM的处理方法就是直接崩溃!!!)

方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型 具有父子关系,直接声明父类即可。

try-catch处理

我们可以发现throws根本没有实际上解决异常,它只是让程序不报错,或者交给别人或者JVM处理,那我们怎么才能真正的处理这个异常呢?这时候就用到我们的try-catch了 。

public static void main(String[] args) {
        try {
            int[] arr = null;
            getElement(arr, 3);
            System.out.println("哈哈");
        } catch (NullPointerException e){
            System.out.println("处理这个异常");
            
            //打印一下在哪里出错了
            e.printStackTrace();
            System.out.println("处理完成");
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("发现异常");
            e.printStackTrace();
        }
        System.out.println("你好");
    }

1.try捕捉到异常后,不执行在try中这个异常后面的程序,所以不打印”哈哈“。

2.明明我的e.printStackTrace()在sout("处理完成")的后面,为什么顺序却反了呢?

答:为什么会出现程序输出偏差呢,先打印sout再打印异常,sout和异常打印不是同个打印,他们存在打印的偏差 不用理会,打印得出来就好了

3.main方法后面的程序继续执行,所以会打印”你好“。(什么时候不会打印呢?交给JVM的时候)如下:

四、finally 

所以引出我们的finaly:不管捕没捕到,都要执行 

    public static void main6(String[] args) {
        //若无法匹配到异常,就交给JVM,让JVM来判断
        try {
            int[] array = {1,2,3};
            System.out.println(array[3]); // 此处会抛出数组越界异常
        }catch (NullPointerException e){ // 捕获时候捕获的是空指针异常--真正的异常无法被捕获到
            e.printStackTrace();
        }finally{
            System.out.println("哈哈");
        }
        //若交给JVM判断的话,JVM收到后中断程序,接下来的代码也不会执行(除了finally)
        System.out.println("后序代码");
    }

在写程序时,有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源:网络连接、数据库 连接、IO流等,在程序正常或者异常退出时,必须要对资源进进行回收。另外,因为异常会引发程序的跳转,可能导致有些语句执行不到,finally就是用来解决这个问题的。

finally一定会被执行吗? 

  1. 当在try块中遇到System.exit()方法时,程序会立即退出,finally块中的代码不会被执行。

  2. 当在try块中遇到无限循环或者死循环时,finally块中的代码不会被执行。

  3. 当在try块中遇到未捕获的异常或Error时,程序会直接跳转到异常处理代码,finally块中的代码不会被执行。

五、throw和throws区别

throw用于主动抛出异常,throws用于声明方法可能抛出的异常类型。

throw是在方法体内部使用的,而throws是在方法的声明处使用的。 

六、异常处理的流程

 【异常处理流程总结】

1.程序先执行 try 中的代码

2.如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.

3.如果找到匹配的异常类型, 就会执行 catch 中的代码

4.如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.

5.无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).

6.如果上层调用者也没有处理的了异常, 就继续向上传递.

7.一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.

七、自定义异常

Java 中虽然已经内置了丰富的异常类, 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我 们实际情况的异常结构 。

具体方法如下:

1. 自定义异常类,然后继承自Exception 或者 RunTimeException

2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因

package demo2;
//Login.java
//自定义
public class Login {
    public String username="admin";
    public String password="123456";

    public void loginInfo(String username, String password) {
        if (!this.username.equals(username)) {
            throw new UserNameException("用户名不匹配");
        }
        if (!this.password.equals(password)) {
            throw new PassWordException("密码不匹配");
        }
        System.out.println("登录成功");
    }

    public static void main(String[] args) {
        try {
            Login login=new Login();
            login.loginInfo("admin","12456");
        }catch (UserNameException e){
            e.printStackTrace();
        }catch (PassWordException e){
            e.printStackTrace();
        }

    }
}



package demo2;
public class PassWordException extends RuntimeException{
    public PassWordException(){

    }public PassWordException(String s){
        super(s);
    }
}



package demo2;
public class UserNameException extends RuntimeException{
    public UserNameException(){

    }
    public UserNameException(String s){
        super(s);
    }
}

注意事项:

自定义异常通常会继承自 Exception 或者 RuntimeException

继承自 Exception 的异常默认是受查异常

继承自 RuntimeException 的异常默认是非受查异常 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1700056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每日练习——同余方程以及格雷码

同余方程 题目描述 运行代码 #include<iostream> #define ll long long using namespace std; ll exgcd(ll a, ll b, ll& x, ll& y) {if (!b)return x 1, y 0, a;ll d exgcd(b, a % b, y, x);y - a / b * x;return d; } int main() {ll a, b, x, y;cin >…

nodeJs上

文章目录 使用node执行js脚本文件流程示例读文件写文件 node构建web服务器流程根据不同请求路径返回不同数据核心模块模块系统ip地址和端口号的概念响应内容类型Content-type 初步实现Apache功能第三方模块 使用node执行js脚本文件 流程 1.创建js脚本文件 2.打开终端&#xf…

5月21号作业

思维导图 代码实现 TCP域套接字服务器 #include <header.h> #include <math.h>int main(int argc, const char *argv[]) {//为通信创建一个端点int sfdsocket(AF_UNIX,SOCK_STREAM,0);//参数1&#xff1a;说明使用的三ipv4通信域//参数2&#xff1a;说明使用的三…

你真的了解HTTPS协议吗

前言 在 HTTP 协议中有可能存在信息窃听或身份伪装等安全问题。使用 HTTPS 通信机制可以有效地防止这些问题。本文即将带大家来了解这些。 任何事物都有两面性&#xff0c;为了满足HTTP协议的快&#xff0c;但导致了它有如下的不足&#xff1a; 通信采用明文&#xff08;不加…

【Linux-INPUT输入的子系统】

Linux-INPUT输入的子系统 ■ input 子系统简介■ input 驱动编写流程■ ■ input 子系统简介 input 子系统就是管理输入的子系统&#xff0c; input 子系统分为 input 驱动层、 input 核心层、 input 事件处理层&#xff0c;最终给用户空间提供可访问的设备节点 ■ input 驱…

模仿高效网络进行目标检测——知识蒸馏

摘要 链接&#xff1a;https://openaccess.thecvf.com/content_cvpr_2017/papers/Li_Mimicking_Very_Efficient_CVPR_2017_paper.pdf 当前的基于卷积神经网络&#xff08;CNN&#xff09;的目标检测器需要从预训练的ImageNet分类模型中初始化&#xff0c;这通常非常耗时。在本…

【除自身以外数组的乘积】python

目录 思路&#xff1a; 代码&#xff1a; 思路&#xff1a; 直接计算前缀乘积&#xff0c;后缀乘积&#xff0c;然后相乘即可 开始我还在想&#xff0c;遍历一次i&#xff0c;怎么能同时计算前缀乘积和后缀乘积&#xff0c;事实上分开计算比较方便。。 代码&#xff1a; cl…

数据集002:眼疾识别数据集 (含数据集下载链接)

说明 病理性近视&#xff08;Pathologic Myopia&#xff0c;PM&#xff09;的医疗类数据集&#xff0c;包含1200个受试者的眼底视网膜图片&#xff0c;训练、验证和测试数据集各400张。 说明&#xff1a; 如今近视已经成为困扰人们健康的一项全球性负担&#xff0c;在近视人…

CMS Full GC流程以及调优配置

个人博客 CMS Full GC流程以及调优配置 | iwts’s blog CMS CMS 收集器是以实现最短 STW 时间为目标的收集器&#xff0c;所以对于偏业务的后台开发而言&#xff0c;基本上都无脑选CMS了。 多线程收集器&#xff0c;工作在老年代&#xff0c;采用标记清除算法。比较特殊&am…

Three.js 研究:3、创建一个高科技圆环

打开Alpha混合 修改环形颜色&#xff0c;更改发光的颜色&#xff0c;更改发光的强度为2 更改世界环境灯光

基于集成经验模态分解的心电信号降噪和基于希尔伯特变换的R峰检测(MATLAB R2018)

近年来&#xff0c;心脏病已成为危害人类健康最常见的疾病。为了有效预防心脏疾病的发生&#xff0c;往往需要更加准确地采集与诊断心电信号&#xff0c;以便于更好地反映心脏情况。心电信号作为人体生理信号&#xff0c;对于识别心脏异常和心脏疾病具有重要的参考价值。心电信…

Docker 常用命令大全!!

Docker 常用命令 一、启动类1. 启动 docker2. 关闭 docker3. 重新启动 docker4. docker 设置自启动5. 查看 docker 运行状态6. 查看 docker 版本号等信息7. docker 帮助 二、 镜像类1. 查看镜像2. 搜索镜像3. 拉取镜像4. 运行镜像5. 删除镜像6. 加载镜像7. 保存镜像 三、容器类…

电机转速计算(基于码盘和IO外部中断)

目录 概述 1 硬件介绍 1.1 整体硬件结构 1.2 模块功能介绍 2 测速框架介绍 2.1 测速原理 2.2 软件框架结构 3 使用STM32Cube配置Project 3.1 准备环境 3.2 配置参数 3.3 生成Project 4 功能实现 4.1 电机控制代码 4.2 测试代码 4.3 速度计算 5 测试 5.1 编写测…

0基础认识C语言

为了给0基础一个舒服的学习路径&#xff0c;就有了这个专栏希望带大家一起进步。 话不多说&#xff0c;开始正题。 一、C语言的一段小历史 C语言的设计要追溯到20世纪60年代末和70年代初&#xff0c;在那个时代美国有这么一号人叫做丹尼斯.里奇&#xff0c;他和同事肯.汤普逊…

pyqt 浮动窗口QDockwidget

pyqt 浮动窗口QDockwidget QDockwidget效果代码 QDockwidget QDockWidget 是 PyQt中的一个控件&#xff0c;它提供了一个可以停靠在主窗口边缘或者浮动在屏幕上的窗口小部件&#xff08;widget&#xff09;。QDockWidget 允许用户自定义其界面&#xff0c;并提供了灵活的停靠和…

【数据结构】栈和队列超详细解析

最重要的就是不要去看远方模糊的&#xff0c;而要做手边清楚的事。&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;栈 • &#x1f330;1.什么是栈&#xff1f; • &#x1f330;2.如何实现栈 • &#x1f330;3.栈的基本操作…

一文教你使用stream流轻松解决java项目数据枚举显示问题

本篇文章主要讲解java枚举、vo实体类通过stream流形式输出枚举参数的方法。 日期&#xff1a;2024年5月26日 作者&#xff1a;任聪聪 本文代码实例附件&#xff1a;https://download.csdn.net/download/hj960511/89361611 实际效果 可以看到在枚举参数的基础上&#xff0c;我们…

56.合并区间

class Solution {public int[][] merge(int[][] intervals) {// 对 intervals 数组按照每个区间的开始位置进行排序Arrays.sort(intervals, (o1, o2) -> o1[0] - o2[0]);int len intervals.length;// 创建结果数组 res&#xff0c;初始化长度为 intervals 的长度int[][] re…

【Text2SQL 经典模型】TypeSQL

论文&#xff1a;TypeSQL: Knowledge-Based Type-Aware Neural Text-to-SQL Generation ⭐⭐⭐ Code: TypeSQL | GitHub 一、论文速读 本论文是在 SQLNet 网络上做的改进&#xff0c;其思路也是先预先构建一个 SQL sketch&#xff0c;然后再填充 slots 从而生成 SQL。 论文发…

Thinkphp5内核宠物领养平台H5源码

源码介绍 Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码 可封装APP&#xff0c;适合做猫狗宠物类的发信息发布&#xff0c;当然懂的修改一下&#xff0c;做其他信息发布也是可以的。 源码预览 源码下载 https://download.csdn.net/download/huayula/89361685