Javase-异常

文章目录

    • 1. 异常概述
    • 2. 异常的继承结构
    • 3. 自定义异常
    • 4. 异常的处理
    • 5. 异常的使用
    • 6. finally语句块
    • 7. 方法覆盖与异常

1. 异常概述

什么是异常

①什么是异常?有什么用?
1.Java中的异常是指程序运行时出现了错误或异常情况,导致程序无法继续正常执行的现象。例如,数组下标越界,空指针异常,类型转换异常等都属于异常情况,
2、 Java提供了异常处理机制,即在程序中对可能出现的异常情况进行捕捉和处理。异常机制可以帮助程序员更好地管理程序的错误和异常情况,避免程序崩溃或出现不可预测的行为。
3.没有异常机制的话,程序中就可能会出现一些难以调试和预测的异常行为,可能导致程序崩溃,甚至可能造成数据损失或损害用户利益。因此,异常机制是一项非常重要的功能,是编写可靠程序的基础。

异常的存在形式

一句话总结, Java当中异常以类和对象的方式存在, 让我们看下面这一段代码

public class Mainpublic static void main(String[] args){String s = null;System.out.print(s.toString());}}
}

上述代码明显发生了一个著名的异常 – 空指针异常
在这里插入图片描述
那这个异常的底层到底是如何发生的呢, 其实质上是new 了一个空指针异常的对象然后抛出

public class Mainpublic static void main(String[] args){//由于这个运行时异常没有被捕获, 所以直接导致了JVM的终止运行throw new NullPointerException();}}
}

2. 异常的继承结构

异常的继承结构详解

①所有的异常和错误都是可抛出的,都继承了Throwable类。
②Error是无法处理的,出现后只有一个结果:JVM终止。
③Exception是可以处理的。
④Exception的分类

  1. 所有的RuntimeException的子类:运行时异常/未检查异常(UncheckedException)/非受控异常
  2. Exception的子类(除RuntimeException之外):编译时异常/检查异常(CheckedException)/受控异常

⑤编译时异常和运行时异常区别:

  1. 编译时异常特点;在编详阶段必须提前处理,如果不处理编详器报错。
    运行时异常特点;在编译阶段可以选择处理,也可以不处理,没有硬性要求。
  2. 编译时异常一般是由外部环境或外在条件引起的,如网络故障,磁盘空间不足。文件找不到等
    运行时异常一般是由程序员的错误引起的,并且不需要强制进行异常处理

为什么有编译时异常的这个说法

注意:编译时异常并不是在编译阶段发生的异常,所有的异常发生都是在运行阶段的,因为每个异常发生都是会new异常对象的,new异常对象只能在运行阶段完成。那为什么叫做编译时异常呢?这是因为这种异常必须在编译阶段提前预处理,如果不处理编译器报错,因此而得名编译时异常。

图解异常的继承结构
下面我们用starUML工具画一下异常继承体系的简图
(其实异常的机构体系十分庞大, 我们的这个图只是举了几个类作为示例)
在这里插入图片描述

3. 自定义异常

自定义异常的方法就两步

  1. 编写一个异常类继承Exception或者是RuntimeException(原则就是判断是程序员的错还是其他)
  2. 给两个构造方法, 一个无参的, 一个带有一个String参数, 调用父类的构造方法
    这个方法的灵感其实来源于源码, 上面我们的UML类继承图也指出, 其实异常继承机构中真正起作用的是Throwalbe方法

下面我们给出例子

/*** 年龄非法异常类*/
public class IllegalAgeException extends Exception{//无参数的构造方法public IllegalAgeException(){super();}//带有一个参数String的构造方法public IllegalAgeException(String message){super(message);}
}
/*** 名字非法异常类*/
public class IllegalNameException extends Exception{//无参数的构造方法public IllegalNameException() {super();}//带有一个参数String的构造方法public IllegalNameException(String message) {super(message);}
}

完成下面的业务逻辑

自定义异常
①定义两个编译时异常:
IlegalNameException:无效名字异常
IllegallAgeException:无效年龄异常
②完成这样的需求:
1.编写一个用户注册的方法,该方法接收两个参数,一个是用户名,一个是年龄。如果用户名长度在6-12]位,并且年龄大于18岁时,输出用户注册成功。
2.如果用户名长度不是[6-12)位时,让程序出现异常,让llegalNameException异常发生!如果年龄小于18岁时,让程序出现异常,让llegalAgeException异常发生!

下面是我们的实现的代码, 我们先通过throws把异常都抛出给上级

import powernode.exception.IllegalAgeException;
import powernode.exception.IllegalNameException;import java.util.Scanner;/*** 测试的主程序*  本次测试中我们的异常机制强行抛给了Main函数来处理*  而Main函数又上抛给虚拟机JVM进行处理, 而JVM的处理机制就是直接断掉测试程序*/
class ExceptionTest{public static void main(String[] args) throws IllegalNameException, IllegalAgeException {Scanner sc = new Scanner(System.in);System.out.println("请输入名字 : ");String name = sc.next();System.out.println("请输入年龄 : ");int age = sc.nextInt();UserService userService = new UserService();userService.register(name,age);}
}/*** 下面是用户层, 用于接收用户的处理请求*/
public class UserService {public void register(String name, int age)  throws IllegalAgeException, IllegalNameException {System.out.println("当前用户正在注册...");Sql sql = new Sql();sql.save(name,age);System.out.println("注册任务已完成...");}
}/*** 下面是数据库层, 用来连接数据库, 在数据库中保存相关的用户信息*/
class Sql {public void save(String name, int age) throws IllegalAgeException, IllegalNameException {//在这里对传入的参数进行处理操作if (name.length() < 6 || name.length() > 12) {throw new IllegalNameException();}if (age < 18) {throw new IllegalAgeException();}System.out.println("您的个人信息在数据库中保存成功...");}
}

4. 异常的处理

  1. 声明异常: 这是一种推卸责任的处理方式, 在方法定义的时候通过throws关键字声明异常, 告诉使用者我们的这个位置可能会出现异常, 这种处理异常的态度是, 如果发生了异常我们就上抛给调用者去解决
  2. 捕获异常: 真正意义上的去处理异常, 通过try-catch的方法进行抓住, 如果其他方法调用这个方法的时候, 如果在方法内部已经抓住了, 那么对于调用者来说是不知道异常发生的
  3. 对于运行时异常来说, 我们没有必要进行强制的处理, JVM会自动的将异常向上抛出(throws处理), 所以我们之前发生空指针异常的时候, JVM得到了异常信息之后就会直接的关掉程序
  4. 对于编译时异常来说, 就需要我们手动的处理, 我们可以选择throws把问题抛给上级, 也可以选择try-catch自己捕获住
  5. 对于异常的处理态度应该是声明跟捕获联合使用
  6. 如何进行选择: 如果异常的发生是需要调用者知道的那我们就进行throws抛出, 否则采用捕获

throws方法的具体语法
在这里插入图片描述
try-catch的基本语法
在这里插入图片描述

上面的逻辑的代码采用处理的方式可以改为下面这样

import java.util.Scanner;/*** 测试的主程序*  本次测试中我们的异常机制强行抛给了Main函数来处理, 而Main函数又上抛给虚拟机JVM进行处理, 而JVM的处理机制就是直接断掉测试程序*/
class ExceptionTest{public static void main(String[] args){Scanner sc = new Scanner(System.in);System.out.println("请输入名字 : ");String name = sc.next();System.out.println("请输入年龄 : ");int age = sc.nextInt();UserService userService = new UserService();try{userService.register(name,age);}catch(IllegalAgeException e) {e.printStackTrace();}catch(IllegalNameException e){e.printStackTrace();}}
}

5. 异常的使用

我们比较常用的其实就下面的两种方法

  1. getMessage()
    获取到最初创建异常的时候的传递出去的message(也就是那个字符串)
    其实我们分析源码就可以了解到, 当时我们调用super(message)的时候, 我们的message其实给到了throwable中的一个属性字符串, 现在我们调用getMessage()的时候实质上是返回了该字符串
  2. printStackTrace();
    打印的是异常在堆栈中的信息(也就是我们的红色字体), 该方法返回的时候是符合栈的数据结构的, 所以我们查看异常的时候应该从顶部查看(栈顶)

6. finally语句块

  1. finally语句块的代码是一定会执行的
  2. finally语句块不可以进行单独的使用, 一定要配合try块一起使用
    通常的使用结构是 try - finally / try - catch - finally
  3. finally语句块通常完成资源的释放(因为一定会执行)

思考下面的案例的执行结果

public static int m1(){try{System.out.println("try语句块");return 1;}finally{System.out.println("finally语句块");}
}答案是try语句块finally语句块
public static int m1(){try{System.out.println("try语句块");System.exit(0);}finally{System.out.println("finally语句块");}
}答案是try语句块

也就是说只有System.exit(0)方法(终止JVM的运行)才能停掉finally语句块的运行

7. 方法覆盖与异常

就一句话, 抛出的异常不可以变多可以变少
如果子类抛出了一个父类抛出异常的父类, 那么这种情况也会编译报错

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

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

相关文章

谷粒商城 - 树形菜单递归流查询、三级分类数据查询性能优化、Jmter 性能压测

目录 树形分类菜单&#xff08;递归查询&#xff0c;强扩展&#xff09; 1&#xff09;需求 2&#xff09;数据库表设计 3&#xff09;实现 4&#xff09;关于 asSequence 优化 性能压测 1&#xff09;Jmeter 安装使用说明 2&#xff09;中间件对性能的影响 三级分类数…

【Kubernetes】Pod 资源调度之亲和性调度

Pod 资源调度之亲和性调度 1.Node 亲和性调度1.1 Node 硬亲和性1.2 Node 软亲和性 2.Pod 亲和性调度2.1 Pod 硬亲和2.2 Pod 软亲和2.3 Pod 反亲和 Kubernetes 的 默认调度器 以 预选、优选、选定机制 完成将每个新的 Pod 资源绑定至为其选出的目标节点上&#xff0c;不过&#…

吴恩达深度学习笔记:机器学习策略(2)(ML Strategy (2)) 2.7-2.8

目录 第三门课 结构化机器学习项目&#xff08;Structuring Machine Learning Projects&#xff09;第二周&#xff1a;机器学习策略&#xff08;2&#xff09;(ML Strategy (2))2.7 迁移学习&#xff08;Transfer learning&#xff09; 第三门课 结构化机器学习项目&#xff0…

学习笔记——动态路由——IS-IS中间系统到中间系统(区域划分)

三、IS-IS区域划分 根据IS-IS路由器邻居关系&#xff0c;可以将IS-IS划分为两个区域——骨干区域和非骨干区域。&#xff08;注意&#xff0c;这里的区域不是上文中提到的Area ID&#xff09;由L2的IS-IS邻居构成的区域为骨干区域&#xff0c;由L1的IS-IS邻居构成的区域为非骨…

智能运维场景探索 | 运营分析

【本场景来源于 擎创科技《一体化数智运维AIOps解决方案》白皮书&#xff0c;经过重新编写】 该场景主要围绕生产运行、运营决策两个维度进行展开&#xff0c;通过对配置、性能、业务等运行数据的加工计算&#xff0c;形成可量化运营效果、可衡量发展方向的运营数据。整体以低…

如何在Spring Boot中使用gRPC

如何在Spring Boot中使用gRPC 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Spring Boot应用中集成和使用gRPC&#xff0c;这是一种高性能…

基于Qt实现的PDF阅读、编辑工具

记录一下实现pdf工具功能 语言&#xff1a;c、qt IDE&#xff1a;vs2017 环境&#xff1a;win10 一、功能演示&#xff1a; 二、功能介绍&#xff1a; 1.基于saribbon主体界面框架&#xff0c;该框架主要是为了实现类似word导航项 2.加载PDF放大缩小以及预览功能 3.pdf页面跳转…

android调用openssl库

android 调用openssl库 一、openssl安装编译 下载openssl-1.1.1w.tar.gz和android-ndk-r21e-linux-x86_64.zip解压android-ndk-r21e-linux-x86_64.zip到/opt/pj_ssl目录下&#xff0c;然后配置环境 vim ~/.bashrc增加如下内容 export NDK_HOME/opt/pj_ssl/android-ndk-r21e…

Python基础小知识问答系列-高效遍历多个不同类型元素的迭代器

1. 问题&#xff1a; 当需要对多个迭代器进行相同遍历操作时&#xff0c;如何避免因为迭代器之间的类型或者迭代器元素 数量过大引发的问题&#xff1f; 2. 解决方法&#xff1a; 使用itertools模块中的chain函数。 示例&#xff1a; from itertools import chainlist_a [2,…

MySQL SQL查询执行顺序解析

目录 MySQL SQL查询执行顺序解析一、MySQL SQL查询的基本概念和特点SQL的特点 二、MySQL SQL查询的执行顺序查询语句的顺序参数的执行顺序实际案例 三、查询执行过程中的关键步骤和组件索引查询缓存查询执行 四、如何优化MySQL SQL查询性能1. 使用合适的索引2. 优化查询语句3. …

matlab 抛物线图像绘制

抛物线图像绘制 x^2y4绘制结果 x^2y4 clc,clear,close all; length10; % 创建一个范围内的 x 和 y 值 x linspace(-length, length, 1000); y linspace(-length, length, 1000);% 创建一个网格来表示 x 和 y 值的组合 [X, Y] meshgrid(x, y);% 计算方程的左边和右边的值 LH…

【ARMv8/v9 GIC 系列 5.5 -- IRQ 和 FIQ中断路由的详细介绍】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 Interrupt assignment to IRQ and FIQ signalsGroup 0物理中断Group 1物理中断不同状态下的中断信号汇总当EL3使用AArch64状态时当EL3使用AArch32状态时只支持单一安全状态的系统小结Interrupt assignment to IRQ and FIQ signals …

网络协议 | MQTT协议草案5.0中文版

MQTT协议草案5.0中文版 by hui6075 最新版本: v0.0.1 2018-05-18 (部分3.3.1版本内容翻译引用 mcxiaoke) 文档地址 中文翻译项目 概述 MQTT是一个客户端-服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范&#xff0c;易于实现。这些特点使…

QWidget成员函数功能和使用详细说明(四)(文字+用例+代码+效果图)

文章目录 1.测试工程配置2.成员函数2.1 void setParent(QWidget *parent)2.2 void setMouseTracking(bool enable)2.3 bool hasMouseTracking() const2.4 void setPalette(const QPalette &)2.5 const QPalette &palette() const2.6 int QWidget::grabShortcut(const Q…

Centos7离线安装mysql-5.7.44bundle包

在 CentOS 7 上安装 mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar&#xff08;这里假设这是一个包含多个 RPM 包的 tar 归档文件&#xff09;的步骤通常涉及解压归档文件、安装 RPM 包以及配置 MySQL 服务。以下是一个详细的步骤指南&#xff1a; 1. 下载和解压 RPM 包 首先&am…

实战干货,企业在数字化转型中如何通过最佳实践落地BI报表?

引言&#xff1a;上一篇文章我们提到&#xff1a;通过9大步骤&#xff0c;帮助企业在数字化转型中搭建数据分析的报表体系&#xff01;在实际中的落地过程&#xff0c;通过实施服务的哪些最佳实践可以确保落地效果&#xff0c;达到项目预期目标&#xff0c;给客户带来实质价值&…

香蕉云编+uniapp打包ios的开发包和生产包

登录香蕉云编&#xff0c;找到 云编-ios证书生成&#xff0c;新建CSR文件&#xff0c;并下载csr文件。 登录苹果开发者中心&#xff0c;进入证书页面。 1.创建一个证书&#xff0c;选择ios Distribution类型即可&#xff0c;这是个通用的证书&#xff0c;既能用来打正式包又能…

UML-概述

统一建模语言 是一种专门为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言。UML是面向对象设计的建模工具。它是一种图形化、图标式的一种语言。 软件开发声明周期 做需求–> 形成需求文档 --> 系统设计&#xff08;写代码之前的准备工作&#xff09;–&g…

PyQt5动态热力图清空画布关闭ColorBar

PyQt5生成正弦波动态热力图清空画布关闭ColorBar 1、简介 生成随机正弦波,使用pyqtgraph展示出来,并且使用热力图展示不同频率的正弦波,使用不同的画布颜色显示热力图的变化。 使用python3.8 导入库: pip install matplotlib==3.7.5 pip install numpy==1.24.4 pip in…

“郭有才”商标主要类别都已被注册!

前阵山东网红“郭有才”火遍大江北&#xff0c;当然少不了许多想去申请注册“郭有才”商标名称的&#xff0c;普推商标知产老杨检索&#xff0c;发现“郭有才”商标申请了43个类别&#xff0c;基本上类别都被申请注册&#xff0c;已注册的商标大多是在“郭有才”火之前申请注册…