Java的异常处理

九. 异常处理

1.try - catch

回忆之前我们对异常的使用,我们用异常改变了方法执行流程

public class TestTry {public static void main(String[] args) {System.out.println(1);test(0.0);System.out.println(3);}public static void test(double p) {if(p <= 0.0) {// 异常也是一个对象, 包含的是错误描述throw new IllegalArgumentException("本金必须大于 0"); // 1 处}System.out.println(2);}
}

输出

1
Exception in thread "main" java.lang.IllegalArgumentException: 本金必须大于 0at com.itheima.module3.TestTry.test(TestTry.java:13)at com.itheima.module3.TestTry.main(TestTry.java:7)

这个例子中,执行到 1 处出现了异常,后续的输出 2、3 的代码都不会执行了

但如果希望,一个方法出现异常后,不要影响其它方法继续运行,可以用下面的语法来处理

public class TestTry {public static void main(String[] args) {System.out.println(1);try {test(0.0);} catch (IllegalArgumentException e) {System.out.println(e);}System.out.println(3);}public static void test(double p) {if (p <= 0.0) {throw new IllegalArgumentException("本金必须大于 0");}System.out.println(2);}
}

输出

1
java.lang.IllegalArgumentException: 本金必须大于 0
3

执行流程为

  • 试着执行 try 块中的代码,如果没异常,一切照旧
  • 现在 try 块内的代码出现了异常:test 方法抛出 IllegalArgumentException 异常对象,异常抛给 test 方法的上一层:main 方法,test 的剩余代码不会执行
  • main 方法中的 catch 能够捕捉 IllegalArgumentException 异常对象,代码进入 catch 块
  • 执行 catch 块内的代码
  • 继续运行后续代码 System.out.println(3)

如果把 catch 的异常类型改为 NullPointerException

  • 那么 catch 捉不住 IllegalArgumentException 异常对象,这个异常对象会继续向上抛,抛给 main 方法的上一层
  • main 方法的上一次是 jvm,当 jvm 收到异常,就会终止整个程序执行

如果不加 try - catch 块,异常对象也会继续从 main 方法抛给 jvm,jvm 收到异常终止程序执行

如果把 catch 的异常类型改为 Exception

  • 那么 catch 也能捉住 IllegalArgumentException 异常对象
  • catch 能不能捉异常,是看实际异常对象和 catch 所声明的异常类型是否满足是一个的关系,即
    • 能够向上转型,就能捉
    • 不能向上转型,就捉不住
  • 异常的继承关系见下一节的图,通常会在 catch 处声明 Exception 类型,这样就能统一捕获它的所有子类异常对象

2. 继承体系

Throwable
String getMessage()
void printStackTrace()
Exception
Error
RuntimeException
IllegalArgumentException
ArrayIndexOutOfBoundsException
ArithmeticException
NullPointerException
  • Throwable 是异常中最顶层的父类
    • getMessage() 提供获取异常信息的功能
    • printStackTrace() 会在【标准错误】输出方法的调用链,用于定位错误位置
  • Error 代表无药可救的异常,通常这种异常就算 catch 也救不了
  • Exception 代表还可以救一救的异常,catch 后可以让程序恢复运行
  • 我们见过的异常有
    • IllegalArgumentException 非法参数异常
    • ArrayIndexOutOfBoundsException 数组越界异常
    • ArithmeticException 算术异常
    • NullPointerException 空指针异常

3. Spring 处理异常

问题:为何之前我们控制器中出现的异常不用 try - catch 处理?

  • 控制器方法是由 Spring 的方法来调用的,因此控制器方法中出现异常,会抛给 Spring 方法
  • Spring 的方法内部用了 try - catch 来捕捉异常,并在 catch 块中会把异常信息作为响应返回

我们当然也能自己 catch 异常,但可悲的是,你就算 catch 住异常又能干什么呢?还得考虑自己如何把异常信息转换为响应,还不如不 catch,交给 Spring 去处理

4. 编译异常与运行时异常

异常按语法可以分成两类

  • 运行时异常(也称未检查异常)
    • Error 以及它的子类
    • RuntimeException 以及它的子类
  • 编译异常(也称检查异常)
    • 除掉运行时以外的所有异常,都属于编译异常

分别举一个例子:throw 一个运行时异常,没有额外语法,此异常抛给上一层方法来处理

public static void test(double p) {if (p <= 0.0) {throw new IllegalArgumentException("本金必须大于 0");}System.out.println(2);
}

如果 throw 一个编译异常

public static void test(double p) {if (p <= 0.0) {throw new Exception("本金必须大于 0"); // 语法报错了!}System.out.println(2);
}
  • 编译异常要求在语法上对异常的处理做出选择,而且选择是强制的,只能下面两个选择二选一
    • 选择1,自己处理:加 try catch 语句
    • 选择2,抛给上一层方法做处理:用 throws 声明
public static void test(double p) throws Exception {if (p <= 0.0) {throw new Exception("本金必须大于 0");}System.out.println(2);
}

但编译时异常的烦人之处在于,当编译时异常抛给上一层方法后,上一层方法也被迫做出类似的选择

5. finally

如果无论是否出现异常,都一定要执行的代码,可以用 finally 语法

try {} catch (Exception e) {} finally {}

其中 catch 不是必须的,可以 try 与 finally 一起用

那这个 finally 的使用场景是什么呢?

以后我们的代码常常需要与一些外部资源打交道,外部资源有文件、数据库等等。这些外部资源使用时都有个注意事项,就是用完后得把资源及时释放关闭,资源都是有限的,如果用完不关,最终会导致资源耗尽,程序也无法继续运行了。将来这边代表资源的对象一般都会提供一个名为 close 的方法,用来释放资源。显然在 finally 中调用资源的 close 方法最为科学

public class TestFinally {public static void main(String[] args) {Resource r = new Resource();try {System.out.println("使用资源");int i = 1 / 0;} catch (Exception e) {System.out.println(e);} finally {r.close();}}
}class Resource implements Closeable {@Overridepublic void close() {System.out.println("释放资源");}
}

如果资源实现了 Closeable 接口,那么可以用 try-with-resource 语法来省略 finally

public class TestFinally {public static void main(String[] args) {// try - with - resourcetry (Resource r = new Resource()) {System.out.println("使用资源");int i = 1 / 0;} catch (Exception e) {System.out.println(e);}}
}class Resource implements Closeable {@Overridepublic void close() {System.out.println("释放资源");}
}

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

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

相关文章

docker: 修改容器的端口

修改运行中容器的端口 正在运行的容器端口冲突了&#xff0c;但是还需要这个容器&#xff0c;怎么办&#xff1f;只能修改端口了 过程&#xff1a; 停止需要修改的容器 修改hostconfig.json文件 重启 docker 服务 启动修改容器 停止需要修改的容器 [roottest ~]# docke…

猫头虎分享:已解决RuoYi-Vue3 项目代码生成器默认生成代码使用的Vue2模板代码问题与Vue2升级到Vue3解决方案

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

PHP中一些特征函数导致的漏洞总结

第一部分&#xff1a; 特征函数 接触到几个常用的函数&#xff1a; \\ \\\ md5 intval strpos in_array preg_match str_replacephp用这些函数实现过滤一些代码&#xff0c;漏洞可能有一些特性&#xff0c;利用这些特征代码进行对比&#xff1b;账号密码对比&#xff1b;强制检…

npm 报错 request to https://registry.cnpmjs.org/vue failed, reason:

npm 报错 request to https://registry.cnpmjs.org/vue failed, reason:_qq62581587d2bea的技术博客_51CTO博客 本来是非常简单的一个报错。 正常情况下&#xff0c;按照网上的方法就可以解决问题。 但是我尝试了使用代理、换源、重装node.js&#xff08;但是npm的配置参数没…

由于找不到msvcr120.dll,无法继续执行代码

一、msvcr120.dll作用介绍 msvcr120.dll文件是Microsoft Visual C Redistributable Package的一部分&#xff0c;它是一个动态链接库&#xff08;DLL&#xff09;文件。这个文件在Windows操作系统中提供C运行时库支持&#xff0c;包含了大量系统级函数和对象&#xff0c;这些函…

jetson-inference----docker内运行分类任务

系列文章目录 jetson-inference入门 jetson-inference----docker内运行分类任务 文章目录 系列文章目录前言一、进入jetson-inference的docker二、分类任务总结 前言 继jetson-inference入门 一、进入jetson-inference的docker 官方运行命令 进入jetson-inference的docker d…

数据结构——静态链表

1.定义&#xff1a; &#xff08;1&#xff09;单链表&#xff1a;各个结点散落在内存中的各个角落&#xff0c;每个结点有指向下一个节点的指针(下一个结点在内存 中的地址); &#xff08;2&#xff09;静态链表&#xff1a;用数组的方式来描述线性表的链式存储结构: 分配一…

【业务功能篇133】 Mysql连接串优化性能问题

rewriteBatchedStatementstrue开启了MySQL驱动程序的批量处理功能。 spring.datasource.urljdbc:mysql://localhost:3306/mydatabase?rewriteBatchedStatementstrue 在MyBatis Plus框架中&#xff0c;批量插入是一种高效的数据库操作方式。通过开启rewriteBatchedStatementstr…

Vue3 Teleport 将组件传送到外层DOM位置

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

力扣刷MySQL-第八弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

R语言【taxlist】——dissect_name():将科学名的各个组分解析出来

Package taxlist version 0.2.4 Description 根据命名法的解析程度和特定角色&#xff0c;包含分类单元用法名称&#xff08;学名&#xff09;的字符串由不同部分组成。 因此&#xff0c;带有名称的字符串可以分解成这些部分&#xff0c;同时部分的数量可能表明了分类等级。 …

DAY18--learning English

一、积累 1.tobacco The disturbing History of Tobacco. 令人不安的烟草历史。 2.commodity How commodity Market work. 必需品商店是如何运作的. 3.cane Sugarcane --- 甘蔗 Sugarcane Farm --甘蔗农场 4.decay Tooth decay. 蛀牙 5.compensate Chinese gammer have evlove…

【Web前端实操13】实现100*100的盒子的阴影效果,阴影值自拟

相关知识点&#xff1a; 盒阴影 box-shadow 向框添加一个或多个阴影。 1 box-shadow: h-shadow v-shadow blur spread color inset; 值描述h-shadow必选&#xff0c;水平阴影的位置v-shadow必选&#xff0c;垂直阴影的位置blur可选&#xff0c;模糊距离spread可选&#xf…

Scrapy爬虫在新闻数据提取中的应用

Scrapy是一个强大的爬虫框架&#xff0c;广泛用于从网站上提取结构化数据。下面这段代码是Scrapy爬虫的一个例子&#xff0c;用于从新闻网站上提取和分组新闻数据。 使用场景 在新闻分析和内容聚合的场景中&#xff0c;收集和组织新闻数据是常见需求。例如&#xff0c;如果我…

史上最全知识图谱建模实践(上):本体结构与语义解耦

在“无需复杂图谱术语&#xff0c;7个原则搞定Schema建模”一文中&#xff0c;我们总结了知识建模最佳实践的7个指导原则。本文中&#xff0c;我们将分基础篇、进阶篇&#xff0c;针对不同业务场景的建模需求&#xff0c;由浅及深讲解基于SPG的知识建模的方法和案例&#xff0c…

JS进阶-深入面向对象(三)

看文章可以得到的收获&#xff1a; 1.在日常开发中&#xff0c;我们在声明一个数组对象后&#xff0c;没有声明有map&#xff0c;filter等方法&#xff0c;为什么可以调用这些方法呢&#xff1f; 2. 什么是面向过程思想&#xff0c;什么是面向对象思想呢&#xff1f; 3.JS中…

Python脚本之操作Redis Cluster【二】

本文为博主原创&#xff0c;未经授权&#xff0c;严禁转载及使用。 本文链接&#xff1a;https://blog.csdn.net/zyooooxie/article/details/112484045 之前写过一篇 使用redis-py来操作redis集群&#xff0c; https://blog.csdn.net/zyooooxie/article/details/123760358 &am…

免费的 UI 设计资源网站 Top 8

今日与大家分享8个优秀的免费 UI 设计资源网站。这些网站的资源包括免费设计材料站、设计工具、字体和其他网站&#xff0c;尤其是一些材料站。它们是免费下载的&#xff0c;材料的风格目前很流行&#xff0c;适合不同的项目。非常适合平面设计WEB/UI设计师收藏&#xff0c;接下…

蓝桥杯练习题

题目&#xff1a;每—本正式出版的图书都有一个ISBN号码与之对应&#xff0c;ISBN码包括9位数字、1位识别码和3位分隔符&#xff0c;其规定格式如“x-xXX-XXXxx-x”&#xff0c;其中符号"-"是分隔符(键盘上的减号)&#xff0c;最后—位是识别码&#xff0c;例如O-670…

地球经纬度常用算法

坐标系转换 坐标系知识普及&#xff1a;GIS基础知识 - 坐标系、投影、EPSG:4326、EPSG:3857 - _熊 - 博客园 – Python import mathx_pi 3.14159265358979324 * 3000.0 / 180.0 pi 3.1415926535897932384626 # π a 6378245.0 # 长半轴 ee 0.00669342162296594323 # …