【Java】关于异常你需要知道的事情

文章目录

  • 异常体系
  • 异常声明
  • 捕获多个异常
  • Java中的哪些异常,程序不用捕获处理?【重要】
  • try with resource 异常处理流程
  • foreach中遇到异常
  • 面试题
    • try和finally中都由return

异常体系

异常体系

异常声明

  • 如果声明的是Exception,那么必须要处理
  • 如果声明的是RuntimeException,那么可以不被处理

捕获多个异常

在Java中,如果你希望捕获try代码块中可能抛出的多种异常,有几种不同的方法可以实现:

  1. 多个catch块:为每种异常类型提供一个单独的catch块。每个catch块处理一种特定的异常类型。
try {
    // 可能会抛出多种异常的代码
} catch (ExceptionType1 e1) {
    // 处理 ExceptionType1
} catch (ExceptionType2 e2) {
    // 处理 ExceptionType2
}
// ... 可以根据需要添加更多的 catch 块
  1. 通用的catch块:使用一个通用的catch块来捕获所有未被捕获的异常。这通常不是一个好习惯,因为它隐藏了具体的错误类型,使得调试更加困难。
try {
    // 可能会抛出多种异常的代码
} catch (Exception e) {
    // 捕获所有Exception的子类,不推荐这样做,因为不清楚具体是哪种异常
}
  1. 多异常类型捕获:从Java 7开始,你可以在一个catch块中捕获多个异常类型,使用圆括号将异常类型包围起来。
try {
    // 可能会抛出多种异常的代码
} catch (ExceptionType1 | ExceptionType2 | ExceptionType3 e) {
    // 同时处理 ExceptionType1, ExceptionType2 和 ExceptionType3
}
  1. ** finally 块**:如果无论是否发生异常,都需要执行一些代码(如资源清理),可以使用finally块。finally块总是在trycatch块之后执行。
try {
    // 可能会抛出异常的代码
} catch (ExceptionType1 | ExceptionType2 | ExceptionType3 e) {
    // 处理异常
} finally {
    // 无论是否发生异常都会执行的代码
}
  1. 异常链:当捕获一个异常并且需要抛出一个新的异常时,可以使用Throwable类的addSuppressed()方法或构造函数中的cause参数来保留原始异常的信息,形成异常链。
try {
    // 可能会抛出多种异常的代码
} catch (ExceptionType1 | ExceptionType2 e) {
    throw new WrappedException("Error message", e);
}

在这个例子中,WrappedException是一个新的异常类型,它封装了捕获的异常作为其原因(cause)。

选择使用哪种方法取决于你的具体需求:

  • 如果不同的异常需要不同的处理逻辑,使用多个catch块。
  • 如果你想要记录或以不同方式响应不同类型的异常,可以考虑使用多异常类型捕获。
  • 如果你想要执行一些清理工作,无论是否发生异常,都使用finally块。
  • 如果你想要封装异常并抛出一个新的异常,同时保留原始异常信息,使用异常链。

通常,推荐的做法是尽可能具体地捕获和处理异常,避免使用过于宽泛的异常捕获,这样可以使你的代码更加健壮,并且便于调试。

Java中的哪些异常,程序不用捕获处理?【重要】

在Java中,异常分为两种主要类型:受检异常(Checked Exceptions)和非受检异常(Unchecked Exceptions)。

  1. 受检异常(Checked Exceptions):这些是继承自java.lang.Exception类但不是继承自java.lang.RuntimeException的异常。受检异常必须在方法中被捕获或者声明抛出。编译器会强制要求你处理这些异常,因为它们被认为是可以被预见并处理的情况。例如,IOExceptionSQLException就是受检异常。

  2. 非受检异常(Unchecked Exceptions):这些是继承自java.lang.RuntimeException的异常。非受检异常不需要在方法中被捕获或声明抛出。它们通常表示编程错误,如空指针异常(NullPointerException)、数组越界异常(ArrayIndexOutOfBoundsException)和非法参数异常(IllegalArgumentException)等。

对于非受检异常,程序可以选择不捕获处理,但这通常不推荐,因为不处理这些异常可能导致程序崩溃。然而,有些情况下,你可能决定不捕获特定的非受检异常,原因可能包括:

  • 不可恢复的错误:当异常指示了一种无法恢复或者无需恢复的错误时,例如,程序的配置错误或严重违反了预期的运行时假设,你可能选择不捕获它,让程序崩溃并记录错误日志。

  • 性能考虑:捕获异常是有性能成本的,对于性能敏感的代码段,如果异常发生的概率非常低,你可能选择不捕获。

  • 框架或库的要求:某些框架或库可能要求你不捕获异常,以便它们可以在更高级别处理异常。

  • 简化代码:在某些情况下,异常处理可能会使代码变得复杂,如果异常发生的可能性非常低,且对程序的影响不大,开发者可能会选择不捕获。

尽管如此,通常建议至少对所有可能的受检异常提供处理逻辑,以避免程序因未处理的异常而意外终止。对于非受检异常,即使选择不捕获它们,也应该在设计和文档中明确这一点,并确保它们不会对程序的其他部分产生不良影响。此外,对于关键的应用部分,记录日志是一个好习惯,这样即使程序崩溃,也能够了解崩溃的原因。

try with resource 异常处理流程

  • 这里其实就是要注意,哪几种情况会异常会被catch住
    在这里插入图片描述

foreach中遇到异常

  • foreach循环会自动跳过遍历空集合,如果对于有null值的集合,碰到null时需注意NPE

在Java中,使用foreach(也称为增强型for循环)进行迭代时,不推荐进行元素的removeadd操作,原因如下:

  1. 迭代器失效:在foreach循环中,实际上是使用迭代器来遍历集合的。当你尝试在迭代过程中修改集合(添加或删除元素),会导致迭代器失效,即迭代器不再能够安全地指向集合中的下一个元素。

  2. 并发修改异常:尝试在迭代过程中修改集合可能会抛出ConcurrentModificationException。这是因为foreach循环隐式地为集合创建了一个迭代器,并在每次迭代时使用迭代器的next()hasNext()方法。如果在迭代过程中修改了集合,就会违反迭代器的预期状态,导致异常。

  3. 逻辑错误:即使在某些情况下,如使用ArrayList,你可能会侥幸逃脱没有遇到异常,但这样的操作通常会导致逻辑错误。因为你可能会跳过一些元素或者重复处理一些元素,导致程序行为与预期不符。

  4. 性能问题:即使某些集合类型(如LinkedList)支持在迭代过程中进行添加或删除操作,这样做也可能引起性能问题。因为每个removeadd操作都可能涉及到大量的元素移动和列表的重新链接,这在大型集合上尤其低效。

如果你需要在迭代过程中修改集合,应该使用集合的迭代器来安全地进行这些操作。例如,对于ArrayList,可以先复制需要删除的元素到另一个集合,然后在迭代结束后删除它们:

List<String> list = ...; // 假设这是你的列表
List<String> toRemove = new ArrayList<>();

for (String item : list) {
    if (需要删除的条件) {
        toRemove.add(item);
    }
}

list.removeAll(toRemove);

对于LinkedList,可以直接使用其迭代器进行删除和添加操作:

List<String> list = new LinkedList<>(); // 使用LinkedList
Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {
    String item = iterator.next();
    if (需要删除的条件) {
        iterator.remove();
    }
    // 可以在这里添加新元素到list中,不会导致迭代器失效
}

总之,避免在foreach循环中修改集合是为了确保逻辑的正确性、避免异常和潜在的性能问题。如果需要修改,应该使用集合的迭代器或者其它安全的方法来进行。

面试题

try和finally中都由return

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的合家云社区物业管理平台 - 项目介绍

合家云社区物业管理平台 2.合家云需求&设计 2.1 项目概述 2.1.1 项目介绍 合家云社区物业管理平台是一个全新的 ”智慧物业解决方案“&#xff0c;是一款互联网的专业社区物业管理系统。平台通过社区资产管理、小区管理、访客管理、在线报修、意见投诉等多种功能模块&a…

CSS详解(一)

1、css工作中使用场景 美化网页&#xff08;文字样式、背景样式、边框样式、盒子模型、定位、动画、&#xff09;&#xff0c;布局页面&#xff08;flex布局、响应式布局、媒体查询&#xff09; 2、CSS 规则 通常由两个主要部分组成选择器和样式声明 2.1选择器 选择器指定了…

Opencv | 边缘提取

目录 一. 边缘检测1. 边缘的定义2. Sobel算子 边缘提取3. Scharr算子 边缘提取4. Laplacian算子 边缘提取5. Canny 边缘检测算法5.1 计算梯度的强度及方向5.2 非极大值抑制5.3 双阈值检测5.4 抑制孤立弱边缘 二. 轮廓信息1. 获取轮廓信息2. 画轮廓 一. 边缘检测 1. 边缘的定义…

号卡流量卡分销推广系统源码

这是一个多功能的流量卡推广分销系统PHP源码&#xff0c;它是一套完善的、功能丰富的号卡分销系统&#xff0c;拥有多个接口&#xff0c;包括运营商接口&#xff0c;以及无限三级代理。这是目前市面上最优雅的号卡系统&#xff0c;没有之一。 软件架构说明&#xff1a; 环境要求…

网络原理(qq消息发送原理)

1.网络初识 IP地址 概念&#xff1a; IP地址主要⽤于标识⽹络主机、其他⽹络设备&#xff08;如路由器&#xff09;的⽹络地址。简单说&#xff0c;IP地址⽤于定位主机的⽹络地址。 就像我们发送快递⼀样&#xff0c;需要知道对⽅的收货地址&#xff0c;快递员才能将包裹送到…

多模态视觉大模型(2): 常用模型介绍(CLIP和LLAVA)

文章目录 1.CLIP 讲解1.1 clip 预训练过程1.2 利用clip进行图像分类1.3 CLIP代码详解1.3.1 Image Encoder 和 Text Encoder的实现1.3.2 搭建CLIP模型1.3.3 准备数据1.3.4 Loss的定义1.4 完整代码2.GLIP 讲解2.1 GLIP 介绍2.2 GLIP 网络结构3.Flamingo3.1 模型介绍3.2 Loss 定义…

远程控制软件优化(1)

远程控制软件优化&#xff08;1&#xff09; 第一版存在以下缺点&#xff1a; 1、四大部分中 Robot States 部分过于简陋&#xff0c;不适合放到论文中 2、Lidar BEV 图像显示效果非常差&#xff0c;显示不全且很稀疏 3、视频流传输延时过高&#xff0c;无法实现远程控制 以…

基于OpenMV 双轴机械臂 机器学习

文章目录 一、项目简要二、目标追踪1. 色块识别与最大色块筛选2. PID位置闭环 三、机器学习1. Device12. Device2 四、效果演示 一、项目简要 两套二维云台设备&#xff0c;Device1通过摄像头捕捉目标物块点位进行实时追踪&#xff0c;再将自身点位传到Device2&#xff0c;Dev…

【力扣周赛】第394场周赛

文章目录 1.统计特殊字母的数量2.使矩阵满足条件的最少操作次数 1.统计特殊字母的数量 题目链接 &#x1f34e;该题涉及的小技巧&#xff1a;&#x1f425; &#x1f427;①大写字母和对应的小写字母低5位都是相等的&#xff1b; &#x1f427;②大写字母ASCII二进制第 6 位…

node.js + @elastic/elasticsearch 操作elasticsearch数据库

我这边node.js 使用的是 koa2&#xff0c;elasticsearch是8.11.1版本 官网&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/getting-started-js.html 一、elastic/elasticsearch 连接 elasticsearch数据库 如果elasticsearch没有设…

win c++使用lua环境配置 5.3.5版本

编译lua 下载lua源码&#xff0c;github仓库 使用vs编译源码&#xff0c;新建一个静态库项目(只会生成lib文件)&#xff0c;想要dll的话就新建dll项目&#xff08;有一个lib文件和dll文件&#xff09; 把lua源码下面的文件夹都是&#xff0c;复制到vs项目中 lib目录是我手动…

ResNeXt网络结构

一、简介 在ResNet的基础上&#xff0c;对残差结构的block进行了更新。 ResNeXt网络是一种深度神经网络架构&#xff0c;可以视为对ResNet&#xff08;残差网络&#xff09;的改进和升级。ResNeXt结合了VGG网络的堆叠相同基础模块的策略以及Inception系列网络中的split-trans…

杰发科技AC7840——CAN通信简介(6)_监听模式

参考&#xff1a;http://t.csdnimg.cn/AFFPC 0. 简介 7840支持4种扩展模式&#xff0c;其中监听模式。 监听模式概念 作用: 这里写的用于诊断&#xff0c;实际上我还没有用到&#xff0c;不太理解为啥可以用作诊断。 我的理解是&#xff0c;在多个总线下&#xff0c;使用监听…

装饰器模式【结构型模式C++】

1.概述 装饰器模式是一种结构型设计模式&#xff0c; 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 2.结构 抽象构件&#xff08;Component&#xff09;角色&#xff1a;定义一个抽象接口以规范准备接收附加责任的对象。具体构件&#xff08;Concre…

苍穹外卖绕过微信支付

经过以下改动可实现&#xff1a; 1、不用微信支付端口 2、弹出支付成功的界面 3、数据库修改支付成功后的数据 #在OrderServiceImpl.java里加入Autowiredprivate OrderService orderService; #在OrderServiceImpl.java里的payment函数做以下改动 #图片里有&#xff0c;红色为原…

时间序列生成数据,TransformerGAN

简介&#xff1a;这个代码可以用于时间序列修复和生成。使用transformer提取单变量或者多变时间窗口的趋势分布情况。然后使用GAN生成分布类似的时间序列。 此外&#xff0c;还实现了基于prompt的数据生成&#xff0c;比如指定生成某个月份的数据、某半个月的数据、某一个星期的…

Qt | 窗口的显示及可见性|标题、透明度、启用/禁用|窗口标志、设置其他属性|获取窗口部件、设置父部件|鼠标光标

​显示事件:QEvent::show,处理函数为 showEvent(QShowEvent*) 隐藏事件:QEvent::hide,处理函数为 hideEvent(QHideEvent* ) 01 QWidget 类中与可见性有关的属性 visible:bool 访问函数: bool isVisible() const; virtual void setVisible(bool visible); 02 QWid…

同事上班这样摸鱼,我坐边上咋看他都在专心写代码啊

我边上有个同事&#xff0c;我坐他边上&#xff0c;但是每天看着他都眉头紧锁&#xff0c;忙的不亦乐乎&#xff0c;但终于有一天&#xff0c;我发现了他上班摸鱼的秘诀。 我劝你千万不要学会这4招&#xff0c;要不就该不好好上班了。 目录 1 上班看电影&#xff1f; 2 上班…

LeetCode - LCR 179.查找总价格为目标值的两个商品

一. 题目链接 LeetCode - LCR 179. 查找总价格为目标值的两个商品 解法&#xff08;双指针 - 对撞指针&#xff09;&#xff1a; 算法思路&#xff1a; 注意到本题是升序的数组&#xff0c;因此可以用「对撞指针」优化时间复杂度。 算法流程&#xff1a; 初始化left &#…

算法入门ABC

前言 初学算法时真的觉得这东西晦涩难懂&#xff0c;貌似毫无用处&#xff01;后来的后来&#xff0c;终于渐渐明白搞懂算法背后的核心思想&#xff0c;能让你写出更加优雅的代码。就像一首歌唱的那样&#xff1a;后来&#xff0c;我总算学会了如何去爱&#xff0c;可惜你早已远…
最新文章