2024 Java 异常—面试常见问题

news2025/1/13 3:34:30

目录

一、异常的分类

二、throw和throws都是异常处理的关键字,二者区别。

三、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

四、try-catch-finally 中哪个部分可以省略?

五、常见的 RuntimeException 有哪些?

六、Error 和 Exception 区别是什么?

运行时异常

编译时异常


一、异常的分类

 Java中异常处理的两种方式:(Ctrl + alt + t)

Throwable 是 Java 语言中所有错误与异常的超类。

Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。

Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。

try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。

catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。

finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。

异常出现,throw出来,程序应该就中断了,也不会往下执行。

        通常情况下,如果没有捕获到异常,方法会提前结束并返回错误代码而不是整个程序。这意味着方法无法正常完成任务,并且通过返回错误代码来指示调用方发生了错误。当方法遇到错误或异常情况时,它将停止执行代码并立即返回给调用方。程序虽然将继续执行,但方法已经提前结束了。调用方可以根据方法返回状态进行相应的处理和错误处理。程序将正常退出,但是返回的错误代码不是0,而是表示具体出错情况的其他值。这样,调用方可以根据返回的错误代码进行相应的处理和错误处理。

二、throwthrows都是异常处理的关键字,二者区别。

  throw关键字用于手动抛出一个异常对象。当程序执行到throw语句时,会立即停止当前的执行路径,并将异常对象传递给调用栈中的上层异常处理机制。throw通常用于在代码中主动抛出异常,例如:

throw new IllegalArgumentException("Invalid argument");

  throws关键字用于声明方法可能抛出的异常类型。当一个方法可能引发异常但不处理时,可以使用throws关键字在方法签名中列出可能抛出的异常类型。这样做的目的是向方法的调用者明确表明该方法可能会产生异常,需要进行相应的异常处理。例如: 

public void readFile() throws IOException { // 读取文件的代码 }

在上面的例子中,readFile()方法声明了可能抛出IOException异常,调用该方法的代码需要进行相应的异常处理,例如使用try-catch块来捕获异常或者继续使用throws关键字将异常向上层抛出。

总结一下:

  • throw用于手动抛出一个异常对象。
  • throws用于在方法签名中声明可能抛出的异常类型,以便通知,声明调用者进行相应的异常处理。

三、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?


答:会执行,在 return 前执行。

注意:在 finally 中改变返回值的做法是不好的,如果存在 finally 代码块,try中 return 语句不会立马返回调用者,而是记录下返回值待 finally 代码块执行完毕之后再向调用者返回其值,然后如果在 finally 中修改了返回值,就会返回修改后的值。显然,在 finally 中返回或者修改返回值会对程序造成很大的困扰,C#中直接用编译错误的方式来阻止程序员干这种龌龊的事情,Java 中也可以通过提升编译器的语法检查级别来产生警告或错误。

@SpringBootTest
class MyclocksourceApplicationTests {
    @Test
    void contextLoads() {
        getInt();
    }

    public static int getInt() {
        int a = 10;
        try {
            System.out.println(a / 0); // 这行代码会抛出一个 ArithmeticException 异常
            a = 20; // 这行代码永远不会被执行,因为上面那行会抛出异常
        } catch (ArithmeticException e) {
            a = 30;
            return a; 
            /*
            当执行到 return a 时,return 的值实际上是 30。
            虽然方法要返回,但 finally 块仍会执行。
            */
//return a 在程序执行到这一步的时候,这里不是return a 而是 return 30;这个返回路径就形成了
//但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
//再次回到以前的路径,继续走return 30,形成返回路径之后,这里的a就不是a变量了,而是常量30
        } finally {
            a = 40; // 修改变量 a 的值,但不会影响已经准备返回的值
// 但 return 30 的返回路径已经确定
        }
        System.out.println(a); // 这行代码永远不会被执行
        return a; // 这行代码也永远不会被执行
    }
}
  • 尽管 finally 块将 a 修改为 40,但是因为在 catch 块中已经准备返回 30,这个返回值不会被修改。最终返回的值是 30。
  • 但如果按照下面这样的方式去写,则会:
    public static int getInt() {
        int a = 10;
        try {
            System.out.println(a / 0);
            a = 20;
        } catch (ArithmeticException e) {
            a = 30;
            return a;
        } finally {
            a = 40;
//如果这样,就又重新形成了一条返回路径,由于只能通过1个return返回,所以这里直接返回40
            System.out.println(a);
            return a;
        }
    }

        在 Java 中,finally 块中的 return 语句会覆盖 trycatch 块中的 return 语句。也就是说,如果在 finally 块中有一个 return 语句,那个 return 语句将会成为最终的返回路径,无论之前的 return 语句是什么。 故执行结果:40

四、try-catch-finally 中哪个部分可以省略?

答:catch 可以省略

原因

更为严格的说法其实是:try只适合处理运行时异常,try+catch适合处理运行时异常+普通异常。也就是说,如果你只用try去处理普通异常却不加以catch处理,编译是通不过的,因为编译器硬性规定,普通异常如果选择捕获,则必须用catch显示声明以便进一步处理。而运行时异常在编译时没有如此规定,所以catch可以省略,你加上catch编译器也觉得无可厚非。

理论上,编译器看任何代码都不顺眼,都觉得可能有潜在的问题,所以你即使对所有代码加上try,代码在运行期时也只不过是在正常运行的基础上加一层皮。但是你一旦对一段代码加上try,就等于显示地承诺编译器,对这段代码可能抛出的异常进行捕获而非向上抛出处理。如果是普通异常,编译器要求必须用catch捕获以便进一步处理;如果运行时异常,捕获然后丢弃并且+finally扫尾处理,或者加上catch捕获以便进一步处理。至于加上finally,则是在不管有没捕获异常,都要进行的“扫尾”处理。

五、常见的 RuntimeException 有哪些?


ClassCastException(类转换异常)

IndexOutOfBoundsException(数组越界)

NullPointerException(空指针)

ArrayStoreException(数据存储异常,操作数组时类型不一致)

还有IO操作的BufferOverflowException异常

六、Error 和 Exception 区别是什么?


Error 类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,JAVA 应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复;

通常有 Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等。比如 OutOfMemoryError:内存不足错误;StackOverflowError:栈溢出错误。此类错误发生时,JVM 将终止线程。

这些错误是不受检异常,非代码性错误。因此,当此类错误发生时,应用程序不应该去处理此类错误。按照Java惯例,我们是不应该实现任何新的Error子类的!

Exception 类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。

Exception 这种异常又分为两类:运行时异常和编译时异常。

运行时异常

定义:RuntimeException 类及其子类,表示 JVM 在运行期间可能出现的异常。

特点:Java 编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既"没有通过throws声明抛出它",也"没有用try-catch语句捕获它",还是会编译通过。比如NullPointerException空指针异常、ArrayIndexOutBoundException数组下标越界异常、ClassCastException类型转换异常、ArithmeticExecption算术异常。

此类异常属于不受检异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。虽然 Java 编译器不会检查运行时异常,但是我们也可以通过 throws 进行声明抛出,也可以通过 try-catch 对它进行捕获处理。如果产生运行时异常,则需要通过修改代码来进行避免。例如,若会发生除数为零的情况,则需要通过代码避免该情况的发生!

RuntimeException 异常会由 Java 虚拟机自动抛出并自动捕获(就算我们没写异常捕获语句运行时也会抛出错误!!),此类异常的出现绝大数情况是代码本身有问题应该从逻辑上去解决并改进代码。

编译时异常

定义: Exception 中除 RuntimeException 及其子类之外的异常。

特点: Java 编译器会检查它。如果程序中出现此类异常,比如 ClassNotFoundException(没有找到指定的类异常),IOException(IO流异常),要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。在程序中,通常不会自定义该类异常,而是直接使用系统提供的异常类。该异常我们必须手动在代码里添加捕获语句来处理该异常。

RuntimeException异常和一般异常(受检异常)之间的区别:是否强制要求调用者必须处理此异常,如果强制要求调用者必须进行处理,那么就使用受检异常,否则就选择非受检异常(RuntimeException)。一般来讲,如果没有特殊的要求,我们建议使用RuntimeException异常。

可以根据下图来选择是捕获异常,声明异常还是抛出异常

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

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

相关文章

如何基于Nginx配置代理服务器实现邮件告警

当代企业信息化系统建设中,将内网与公网进行隔离是一种非常常见的措施,它可以有效保护企业内部数据不被外泄,有助于企业构建一个更加安全的网络环境,保护企业资产和用户隐私。但另一方面,内网与公网隔离也会带来一些问…

本地无法连接linux上的MariaDB数据库

使用mysql -u root -p 输入密码: 进去之后没有user表,无法改user、host等信息。

安装Pygame

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Pygame是跨平台的Python模块,专为电子游戏设计(包含图像、声音),创建在SDL(Simple Direct…

QT day01

思维导图 QT编程 实现一个账号登录界面 代码&#xff1a; myweidget.h #ifndef MYWEIDGET_H #define MYWEIDGET_H#include <QWidget> #include <QIcon> //图标类 #include <QLineEdit> //行编辑器类 #include <QLabel> //标签类 #…

GROUP_CONCAT

– select 中可以查询的是 GROUP BY 后的&#xff0c;以及这类 MAX() GROUP_CONCAT(expr) 等 select su.* ,sd.dept_name deptName , sp.post_name postName ,GROUP_CONCAT(sr.role_name),GROUP_CONCAT(sr.id) from sys_user su LEFT JOIN sys_dept sd on su.dept_no sd.dept_…

QtScrcpy最出色的C++开源手机投屏控制软件

QtScrcpy是一款开源的跨平台屏幕录制和投屏工具 基本概述&#xff1a; 它基于Android的ADB&#xff08;Android Debug Bridge&#xff09;和Electron框架&#xff0c;为用户提供了简洁且功能强大的用户界面。 支持平台&#xff1a; QtScrcpy支持Windows、macOS和Linux三大…

Vue配置项之directives

Directives 首先说明一下&#xff0c;本人是前端小学生级别的菜鸡&#xff0c;吐槽的话请口下留情&#xff0c;在评论区指出错误或者补充不足&#xff0c;我会很喜欢&#xff0c;互喷不会进步&#xff0c;相互指点才会。。。。谢谢大家啦 目录 Directives 目录自己定义官网简…

摄影构图:如何处理对焦、快门、光圈、ISO 以及拍摄方式

写在前面 博文内容涉及摄影对焦模式、快门速度、光圈、ISO以及拍摄方式的简单介绍《高品质摄影全流程解析》 读书笔记整理理解不足小伙伴帮忙指正 &#x1f603; 生活加油 99%的焦虑都来自于虚度时间和没有好好做事&#xff0c;所以唯一的解决办法就是行动起来&#xff0c;认真…

嵌入式学习记录6.13(qt day1)

一.思维导图 二.练习&#xff08;简单模拟tim界面&#xff09; 2.1代码 mywidget.cpp #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {this->setWindowTitle("Tim");this->setWindowIcon(QIcon("C:\\Users\\zy\…

第P10周:Pytorch实现车牌识别

第P10周&#xff1a;Pytorch实现车牌识别 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 在之前的案例中&#xff0c;我们多是使用datasets.ImageFolder函数直接导入已经分类好的数据集形成Dataset&#xff…

[面试题]Java【虚拟机】

[面试题]Java【基础】[面试题]Java【虚拟机】 因为 Java 并发涉及到的内容会非常多&#xff0c;本面试题可能很难覆盖到所有的知识点&#xff0c;所以推荐 《深入拆解 Java 虚拟机》 。 走近 Java 什么是虚拟机&#xff1f; Java 虚拟机&#xff0c;是一个可以执行 Java 字…

cilium关闭vxlan

说明 操作 启用标志 yum -y install net-tools.x86_64 ifconfig | grep vxlan cilium_vxlan: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500修改相关配置 ks get cm cilium-config -oyaml | grep -E tunnel|ipv4-native-routing-cidr|auto-direct-node-routes…

python310: pip install Could not install packages (HTTPSConnectionPool)问题

一、问题描述 在使用pip install安装包或者升级pip版本&#xff08;pip install --upgrade pip&#xff09;时遇到以下错误&#xff1a; WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ReadTimeoutError(…

淘宝镜像地址失效

1. 使用nvm安装node时候报错 报错内容 Get "https://npm.taobao.org/mirrors/node/latest/SHASUMS256.txt": tls: failed to verify certificate: x509: certificate has expired or is not yet valid:报错原因 淘宝镜像地址的证书过期了 解决 找到nvm安装的根目…

为什么说掌握心理学知识成为产品经理一门必修课?

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

猫不喝水有什么危害?我想了这招,主食冻干、主食罐头骗水很实用

猫咪如果长期不喝水&#xff0c;一直处于缺水状态&#xff0c;可能会出现一些健康问题。首先&#xff0c;它们可能会出现便秘、上火等症状。在高温的夏季&#xff0c;缺水的猫还容易有脱水中暑的情况&#xff0c;严重的甚至可能死亡。另外&#xff0c;长期饮水不足的猫、很容易…

Chisel入门——在windows系统下部署Chisel环境并点亮FPGA小灯等实验

Chisel入门——在windows系统下部署Chisel环境并点亮FPGA小灯等实验 一、chisel简介二、vscode搭建scala开发环境2.1 安装Scala官方插件2.2 java版本&#xff08;本人用的是jdk18&#xff09;2.3 下载Scala Windows版本的二进制文件2.4 配置环境变量2.5 scala测试2.6 vscode运行…

linuxcentos将本地库JAR/arr批量导入到Nexus3.x

背景 我们现在要搞一个私服maven来管理对应的依赖包&#xff0c;需要上传包。用nexus只能单个文件搞&#xff0c;批量导入不行&#xff0c;而且还要单独配置groupID什么的。不多BB,上教程 建脚本 vi mavenimport.sh内容是这个 #!/bin/bash # copy and run this script to t…

【Linux】进程_2

文章目录 五、进程2. 操作系统3. 进程 未完待续 五、进程 2. 操作系统 我们知道了操作系统是一个进行 软硬件 资源 管理 的 软件 。为什么要有操作系统呢&#xff1f;或者说&#xff0c;为什么要有操作系统的管理呢&#xff1f;操作系统的存在目的是为了对上提供一个良好的运行…

设计通用灵活的LabVIEW自动测试系统

为了在不同客户案例中灵活使用不同设备&#xff08;如采集卡、Modbus模块&#xff09;且保持功能一致的LabVIEW自动测试系统&#xff0c;需要采用模块化的软件架构、配置文件管理、标准化接口和良好的升级维护策略。本文从软件架构、模块化设计、配置管理、升级维护、代码管理和…