2024 Java 异常—面试常见问题

目录

一、异常的分类

二、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.mfbz.cn/a/705173.html

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

相关文章

neo4j-官网学习

1、cypher 代码学习文档 https://neo4j.com/docs/cypher-cheat-sheet/5/auradb-enterprise 2、APOC函数包安装(desktop) 直接点击就可以安装,安装完之后重启一下,Cypher查询中使用CALL apoc.help(‘apoc’)来检查APOC插件是否已…

全网自动观影一条龙!一步到位的极空间nas-tools搭建教程

全网自动观影一条龙!一步到位的极空间nas-tools搭建教程 哈喽小伙伴们好,我是Stark-C~,前几天为大家分享的《极空间全自动小雅Alist以及Emby全家桶部署教程》大家都反映没用上极空间自己强大的“极影视”有点可惜,所以今天再教大…

JasperReport-合并单元格

合并单元格是做报表时经常会遇到的需求。下面列举两种合并单元格的方式。 一、示例一 合并单元格在Subject。 1.1 创建5列的表 1.2 合并Column4和 Column5 按住Ctrl键点击Column4和 Column5,同时选中。然后右键,选择“Group Columns”。 1.3 合并成功 二、示例二 示例一…

VirtualBox 虚拟机中的 centos7 系统拉取 docker 镜像常见报错及解决方法

一、拉取镜像时报错:Error response from daemon: Get "https://registry-1.docker.io/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority 原因:(文心一言给出的原因) 这个错误…

产品经理研读:Agent的九种设计模式(图解+代码)

引言 上周五我在一个特工宇宙的社群里做了一次分享,题目是《从 YC 项目看 AI 趋势以及 AI agent 开发工具类产品该如何设计》,收到了大家不错的反馈,不过回看视频后还是发现不少可以提升的地方,感兴趣的朋友公众号回复“分享”获…

了解AIGC:让AI创造内容,改变未来

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 什么是AIGC? 定义和概念 🧠 关键技术 🤖 AIGC的发展历程 &#x1f…

android studio过滤日志

荣耀手机的日志有很多乱七八糟的输出 在logcat设置过滤 filter name:过滤名称随意 log tag不知道是什么 log message设置过滤的内容或者设置显示的内容 需要过滤的内容: ^(?!.*(gralloc4|InputMethodManager|tagSocket|dataspace)).*$以|分割要过滤的内容 要显…

基于51单片机8x8点阵设计

基于51单片机8x8点阵设计 (仿真+程序) 功能介绍 具体功能: 1.用74HC138驱动8x8点阵; 2.按键可以切换模式; 3.一共4种模式,0~9数字闪出、动态爱心、坦克走动、数字依次向上平移; …

[天翼杯 2021]esay_eval

[天翼杯 2021]esay_eval <?php class A{public $code "";function __call($method,$args){eval($this->code);}function __wakeup(){$this->code "";} }class B{function __destruct(){echo $this->a->a();} } if(isset($_REQUEST[poc]…

减治法思想-二分查找图解案例

减治法介绍 减治法思想 ​ 分治法是将一个大问题划分为若干个子问题&#xff0c;分别求各个子问题&#xff0c;然后把子问题的解进行合并得到原问题的解。 ​ 减治法同样是把一个大问题划分为若干个子问题&#xff0c;但是并不是求解所有的子问题&#xff0c;因为原问题的解…

182.二叉树:二叉搜索树的最小绝对差(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

剧本新纪元:探索短剧系统的魔力

在现代社会&#xff0c;随着科技的迅猛进步和生活节奏的不断加快&#xff0c;传统的长篇电视剧和电影已不能完全满足所有人的需求。短剧&#xff0c;由于其简短、快速、直接的特性&#xff0c;正在逐步成为一种文化新趋势。短剧系统正是这一趋势的典型代表&#xff0c;它以独特…

Ansys Mechanical|使用Trace Mapping建立PCB板的有限元模型

Trace Mapping需要使用ECAD的方法 传统方法 vs ECAD方法 传统方法既繁琐又费时。以下是一些数据&#xff1a; 导出电路板布局的step文件大约需要30分钟。 导入Ansys SpaceClaim中大约需要10分钟。 进行布尔运算和共享拓扑操作大约需要24小时甚至更久。 而ECAD方法更加快速且…

CV每日论文--2024.6.12

1、PGSR: Planar-based Gaussian Splatting for Efficient and High-Fidelity Surface Reconstruction 中文标题&#xff1a;PGSR&#xff1a;基于平面的高斯溅射&#xff0c;用于高效、高保真表面重建 简介&#xff1a;这项研究关注于3D高斯喷洒(3DGS)技术,该技术因其高质量渲…

探索生成式AI的未来:Chat与Agent的较量与融合

近年来&#xff0c;生成式人工智能&#xff08;AI&#xff09;不仅在技术界引起了广泛关注&#xff0c;更成为了推动多个行业革新的关键力量。这种技术之所以备受瞩目&#xff0c;不仅在于其独特的创造性和高效性&#xff0c;还在于它对未来商业模式和社会结构可能产生的深远影…

Java的Mybatis框架中#{}与${}使用心得

Java的Mybatis框架中#{}与${}使用心得 在MyBatis框架中&#xff0c;#{}和${}都是用来动态地向SQL语句中插入值的&#xff0c;但它们的处理方式和用途有所不同 #{} 安全&#xff1a;#{}是预编译处理&#xff0c;能够有效防止SQL注入。它会将参数看作一个占位符&#xff0c;在…

servlet梦想酒店管理系统

梦想酒店管理系统 酒店管理系统分为管理端&#xff0c;和用户端&#xff0c; 用户端可以查看酒店客房&#xff0c;预定酒店系统&#xff0c;查询预定信息。 管理端&#xff1a;用户管理&#xff0c;类型&#xff0c;房间管理&#xff0c;业务管理&#xff0c;统计分析。 技术&…

无文件落地分离拆分-将shellcode从文本中提取-file

马子分为shellcode和执行代码. --将shellcode单独拿出,放在txt中---等待被读取执行 1-cs生成python的payload. 2-将shellcode进行base64编码 import base64code b en_code base64.b64encode(code) print(en_code) 3-将编码后的shellcode放入文件内 4-读取shellcod…

中国地市分布图

中国地市分布图 (qq.com)

ssm学生成绩管理系统-海豚

ssm学生成绩管理系统-海豚 ssm学生成绩管理系统。 功能:登录&#xff0c;学生信息管理&#xff0c;课程信息&#xff0c;成绩信息&#xff0c; 技术&#xff1a;java&#xff0c;ssm&#xff0c;mybatics&#xff0c;jsp 平台&#xff1a;eclispe或者idea&#xff0c;mysql5.7…