初识异常(Java系列10)

news2025/4/24 23:35:22

目录

前言:

1.异常的概念

2.异常的分类

2.1编译时异常

2.2运行时异常 

3.异常的处理

3.1如何抛出异常

3.2异常的捕获

3.2.1异常的声明

3.2.2try-catch捕获并处理

3.3异常的处理流程

4.自定义异常类

结束语:


前言:

相信在大家学习Java和敲代码的过程中会时不时的出现一些问题,有些是编译器自己报出来的错误,有些是我们自己手动排除的错误,那么在编译器报出一些错误的时候就会有助于我们更快的找到代码的错误,可以更好更快的解决这个问题,那么编译器出现的这种情况就是异常,接下来就和小编从下面的几个方面来了解一下什么是异常,最后我们如果要自己编写一个异常又该如如何去写呢?话不多说,上干货!!!

1.异常的概念

 在生活中程序猿是一群办事严谨、追求高科技的技术性人才,所以在日常的开发中会绞尽脑汁的将代码写的尽善尽美,但是在程序运行的过程中,难免会出现一些奇奇怪怪的问题,有时候通过代码很难去控制,比如数据格式不对、网络不通畅、内存报警等。在Java中将程序执行过程中发生的不正常行为称为异常。

比如我们之前遇到过的:

1.算数异常

2.数组越界异常

3.空指针异常

2.异常的分类

首先我们先来看一下异常的体系结构:

从上图中我们可以看到:

  • Throwable:是异常体系的顶层类,其派生出两个子类:Error和Exception。
  • Error:指的是java虚拟机无法解决的问题,比如:Java的内部错误,资源耗尽等,一旦发生就需要程序员来解决。
  • Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。 

那么接下来我们就看一下异常的两大类:编译时异常和运行时异常。

2.1编译时异常

在程序编译期间发生的异常,称之为编译时异常,也称之为受检查异常

下面出现的就是编译时异常

 在编译时异常时我们需要声明一下异常,这个我们后面会讲到的。

2.2运行时异常 

在程序执行期间发生的异常,称之为运行时异常,也称之为非受检查异常。如下所所示:

RunTimeException以及其子类对应的异常,都称之为运行时异常。要注意的是在编译的时候出现的语法性错误不叫异常。

3.异常的处理

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

那么下面我们就分别看一下这几个关键字。

3.1如何抛出异常

在编写程序时,如果程序出现错误,此时就需要将错误的信息告知给调用者,那么在Java中我们可以通过throw关键字来抛出一个异常对象,将错误的信息告知给调用者。

throw new XXXXException("异常产生的原因");

注意:

  • throw必须写到方法体内部。
  • 抛出的对象必须是Exception或者Exception的子类对象。
  • 如果抛出的是RunTimeException或者RunTimeException的子类,则可以不用处理,直接交给JVM来处理。
  • 如果抛出的是编译时异常,用户必须处理,否则无法通过编译。
  • 异常一旦抛出,其后的代码就不会执行。 

代码如下所示:

public class Test2 {
    public static void getArray(int[] array) {
        if(null == array) {
            throw new NullPointerException("空指针异常!!!");
        }
        for (int i = 0; i < array.length; i++) {
            if (i > array.length) {
                throw new ArrayIndexOutOfBoundsException("数组越界异常!!!");
            }
            System.out.print(array[i] + " ");
        }
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7,8,9,10};
        getArray(array);
    }
}

 正常执行代码结果下所示:

 如果中途出现异常的情况下:

代码如下所示:

public class Test2 {
    public static void getArray(int[] array) {
        if(null == array) {
            throw new NullPointerException("空指针异常!!!");
        }
        for (int i = 0; i < array.length; i++) {
            if (i > array.length) {
                throw new ArrayIndexOutOfBoundsException("数组越界异常!!!");
            }
            System.out.print(array[i] + " ");
        }
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7,8,9,10};
        int[] array2 = null;
        getArray(array2);
        getArray(array);
    }
}

异常情况下结果如下所示:

代码不会再继续往下运行!!!

3.2异常的捕获

那么出现异常后我们应该如何处理呢?此时我们就需要异常的捕获了,处理方式主要有两种:异常的声明和try-catch捕获异常。

3.2.1异常的声明

语法格式:

修饰符  返回值类型  方法名(参数列表)throws 异常类型1,异常类型2……{

}

代码如下所示:

public class Test3 {
    public static int Div(int x, int y) throws ArithmeticException{
        return x / y;
    }
    public static void main(String[] args) throws ArithmeticException{
        System.out.println(Div(2, 3));
    }
}

注意:

  • throws必须跟在方法的参数列表之后。
  • 声明的异常必须是Exception或者Exception的子类。
  • 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可。
  • 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出。

3.2.2try-catch捕获并处理

在上述的throws其实并未对异常进行处理而只是将异常报告给抛出异常方法的调用者,由调用者处理,如果真正要对异常进行处理,就需要try-catch。

语法格式:

try {
    //将可能出现异常的代码放到这里面
}catch (要捕获的异常的类型 e) {
    //如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常的类型一致时,或者是try中抛出异常的基类时,就会被捕获到。
    //对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后续代码。
}finally {
    //此处的代码一定会被执行到
}
//后续的代码
//当异常被捕获到时,异常就被处理了,这里的代码一定会被执行
//如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行。

示例代码如下所示:

import java.util.Scanner;

public class Test5 {
    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(System.in)){
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            System.out.println(a / b);
            int[] array = {1,2,3,4,5};
            System.out.println(array[5]);
        }catch (ArithmeticException e) {
            e.printStackTrace();//打印红字
            System.out.println("捕捉到了ArithmeticException异常!!!");
            //写进行处理的逻辑
        }catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
            //可以通过 | 来进行多个异常的捕获
            e.printStackTrace();
            System.out.println("捕捉到了NullPointerException| ArrayIndexOutOfBoundsException异常!!!");
            //写进行处理的逻辑
        }finally {
            System.out.println("finally一般用于资源的释放!!!");
        }
    }
}

 结果如下所示:

注意:

  • try块内抛出异常位置之后的代码块将不会被执行。
  • 如果抛出异常类型与catch捕获的类型不匹配,即异常不会被成功捕获成功,也就不会被处理,继续往外抛异常,直到JVM收到中断程序。
  • try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获,即多个异常,多次捕获。
  • 如果多个异常的处理情况是完全相同的,那么我们就可以通过“ | ”来进行分隔。
  • 如果异常之间存在父子关系,那么一定是子类异常的catch在父类异常的catch之前,否则就会出现语法错误。
  • 可以通过一个catch(Exception)捕获所有异常,即多个异常,一次捕获。但是不推荐。

3.3异常的处理流程

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

4.自定义异常类

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

具体方式如下所示:

  • 自定义异常类,然后继承Exception或者是RunTimeException。
  • 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因。
  • 继承自Exception的异常默认是受查异常。
  • 继承自RunTimeException的异常默认是非受查异常。

下面我们通过一个登录界面来说明一下自定义异常,以及在将前面的知识串起来。

登录界面:

代码如下所示:

public class Test {
    public static void main(String[] args) {
        Login login = new Login("admin","1234");
        try {
            login.button("admin","123");
        }catch (UserNameException e) {
            e.printStackTrace();
            System.out.println("用户名异常!");
        }catch (PasswordException e) {
            e.printStackTrace();
            System.out.println("密码错误!");
        }finally {

        }
    }
}
public class Login {
    private String name = "admin";
    private String password = "1234";

    public Login(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public void button (String name, String password) throws UserNameException , PasswordException{
        if (!this.name.equals(name)) {
            throw new UserNameException("你的用户名错了!!!");
        }
        if (!this.password.equals(password)) {
            throw new PasswordException("你的密码错了!!!");
        }
    }
}

 

public class PasswordException extends RuntimeException{
    public PasswordException() {
        super();
    }
    public PasswordException(String s) {
        super();

    }
}

 

public class UserNameException extends RuntimeException{
    public UserNameException() {
        super();
    }
    public UserNameException(String name) {
        super(name);
    }
}

结果如下所示:

 

 

结束语:

这次小编主要和大家分享了异常的一些基础知识,也给大家示范了一个简易版的登录,希望对大家有所帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

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

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

相关文章

Windows常用命令整理

之前写了一篇关于Windows快速打开服务_陌客依天涯的博客-CSDN博客_服务快捷键 的文章&#xff0c;有表示windows还有很多常用的&#xff0c;那就整理一下&#xff0c;分享跟多点&#xff0c;希望对大家有用。 1、mstsc /*快速开启远程连接客户端*/ 2、regedit /*快速打开注册…

AcWing 1227.分巧克力(二分)

一、题目信息 二、思路分析 先从数据范围入手&#xff0c;这道题的数据范围最大是10的5次方&#xff0c;这就说明我们解决问题时的用到的算法的时间复杂度要控制在O(n)O(n)O(n)或者O(nlog(n))O(nlog(n))O(nlog(n))。 而O(nlog(n))O(nlog(n))O(nlog(n))的算法中最常用的是二分或…

基于RateLimiter+Aop+自定义注解实现QPS限流

QPS秒级限流一、Aop二、自定义注解三、测试类实例QPS简介&#xff1a;QPS&#xff08;Query Per Second&#xff09;&#xff0c;QPS 其实是衡量吞吐量&#xff08;Throughput&#xff09;的一个常用指标&#xff0c;就是说服务器在一秒的时间内处理了多少个请求 —— 我们通常…

控制流分析之构建支配树

控制流分析之构建支配树引言1 分析有向图2 构建支配树2.1 求最小半支配点2.2 求最近支配点引言 如上一个带有起始入口点的有向图为例&#xff0c;从A到Q的必经结点有A、L、M、Q&#xff0c;我们称其为Q的支配点&#xff0c;其中M为Q的最近支配点。我们将每个结点的最近支配结点…

分享124个PHP源码,总有一款适合您

PHP源码 分享124个PHP源码&#xff0c;总有一款适合您 源码下载 链接&#xff1a;https://pan.baidu.com/s/1AIktEQ0-cPRoSSAw_eA2Lw?pwdfb9m 提取码&#xff1a;fb9m 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0…

2022 Apache APISIX 年度记忆

时光已逝&#xff0c;转眼 2022 年已然落下了帷幕。Apache APISIX 社区在众多开源爱好者和开发者的陪伴下&#xff0c;又一起走过了新的四季。 在过去的一年中&#xff0c;我们的开源项目和社区都取得了许多成就&#xff0c;并得到了来自全球范围的广泛关注和支持。2022 年&am…

数据库管理与表文件管理

数据库管理&#xff1a; 1.MySql服务器管理数据库位置&#xff1a;C:\ProgramData\MySQL\MySQL Server 5.5\data 2.查看所有的数据库名 show databases; mysql> show databases;&#xff08;查看有哪些数据库 这属于MySql的命令&#xff0c;不属于SQL语句&…

硅基仿生业务全面 Serverless 容器化,14万+问答库助力糖尿病科普

作者&#xff1a;宁佑章&#xff08;硅基仿生科技&#xff09;、元毅&#xff08;阿里云容器服务&#xff09; “使用阿里云容器服务 Knative&#xff0c;解决了开发迭代慢的问题&#xff0c;加速了深度学习模型的性能提升&#xff1b;同时提供了弹性可伸缩的资源配置&#xf…

关于Linux宝塔面板nginx配置关于php项目的跨域请求

1、网上有好多跨域请求的案例。最多的如下&#xff1a; 在项目下的配置文件中添加&#xff1a; #add_header Access-Control-Allow-Origin * always; #add_header Access-Control-Allow-Credentials true; #add_header Access-Control-Allow-Methods GET,POST,OPTIONS…

新库上线 | CnOpenData中诚信绿金ESG评级数据

中诚信绿金ESG评级数据 一、数据简介 在碳达峰、碳中和的时代浪潮下&#xff0c;以环境、社会、公司治理为核心的ESG投资理念迅速成为发现资本市场投资机遇、规避投资风险的利器。中诚信绿金在多年信用评级经验的基础上通过建立契合国内政策趋势、信息披露现状、行业发展情况…

applicationContext讲解

applicationContext讲解 生成bean 豆子&#xff0c;bean工厂&#xff0c;对象的工厂 id是对象名&#xff0c;豆子的名字&#xff0c;全项目唯一&#xff0c;class是类全路径名 bean标签的底层实现是无参构造方法 <bean id"book1" class"com.nz.entity.Book&q…

【BFS 广度优先搜索】详解感染橘子最短时间问题

一、题目描述 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直…

nginx在linux上的部署

第一步、虚拟机安装新建虚拟机&#xff08;创建的时候记得打开网络连接&#xff0c;使用nat转换的方式&#xff09;linux配置上网第一种方式&#xff1a;自动获取&#xff0c;将ipv4设置为dhcp的自动获取。但是这样每次获取的ip可能不一样。使用xshell连接的时候可能需要修改。…

第四十一讲:神州防火墙透明模式的初始配置

现在要求把防火墙接入到现有的局域网中&#xff0c;尽量不改变已有的LAN架构和IP 地址分配&#xff0c;还能对内网的流量管理进行管理&#xff0c;起到对内网的安全保护作用。防火墙接入要求&#xff0c;应该选择防火墙的工作模式为透明模式。透明模式对原有网络的介入最少&…

把PBP、前端对接、钉钉集成玩透的考试系统

文/刘俊良 周亮 年佳斌 编辑/杜逸敏 一、项目背景 客户需要开发一套企业内部的考试系统&#xff0c;用于企业内部规章制度的学习及考核。系统的主要功能包括&#xff1a; 每个员工都可以进行每日答题与专项答题。根据答题结果&#xff0c;归类不同的题库以供员工查询学习。…

进击的 AI 生成,创造性的新世界!

2022年&#xff0c;AI艺术生成文本生成图像的AI绘画生成器如雨后春笋般涌现&#xff0c;以一幅幅“不明觉厉”的AI作品进入大众视野。从2月Disco Diffusion爆火&#xff0c;仅两个月后OpenAI发布DALL-E 2&#xff0c;谷歌和Meta紧随其后宣布了各自的AI”画家“Imagen和Make-A-S…

尚医通-排班规则接口-排班详情接口-前端整合(二十五)

目录&#xff1a; &#xff08;1&#xff09;医院排班-排班规则接口 &#xff08;2&#xff09;医院排班-排班规则-前端整合 &#xff08;3&#xff09;医院排班-排班详情接口 &#xff08;4&#xff09;医院排班-排班详情前端整合 &#xff08;1&#xff09;医院排班-排班…

一文分析Linux虚拟化KVM-Qemu分析之内存虚拟化

说明&#xff1a; KVM版本&#xff1a;5.9.1QEMU版本&#xff1a;5.0.0工具&#xff1a;Source Insight 3.5&#xff0c; Visio 1. 概述 深入分析Linux虚拟化KVM-Qemu之ARMv8虚拟化文中描述过内存虚拟化大体框架&#xff0c;再来回顾一下&#xff1a; 非虚拟化下的内存的访问…

剑指 Offer 07. 重建二叉树

剑指 Offer 07. 重建二叉树 一、题目 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 Input: preorder [3,9,20,15,7], inorder [9,3,15,20,7] Output: [3,9,20,null,null,1…

ansible第三天作业

1.挂载本地光盘到/mnt 2.配置yum源仓库文件通过多种方式实现 仓库1 &#xff1a; Name: RH294_Base Description&#xff1a; RH294 base software Base urt: file:///mnt/BaseOS 不需要验证钦件包 GPG 签名 启用此软件仓库 仓库 2: Name: RH294_Stream Description …