网站首页 > java教程 正文
大家好,我是徒手敲代码。
今天分享面试中,常见的几个异常问题。在看面试题之前,首先要问问自己,究竟什么是异常,怎么理解异常呢?
从字面上看,异常就是不正常的意思。如何定义不正常呢?做饭之前,买好了苦瓜,买好了牛肉,本来想做个番茄炒蛋。结果家里停电停水,天意弄人。像这些意外情况,让我们无法继续把做饭这个动作进行下去,只能停下来,解决了停电停水这个问题,才能继续,这就是异常。
回到编码上,当我们运行Java程序的时候,JVM会按照字节码,一行一行地运行下去,注意不一定按照我们写的顺序来的喔(这和万恶的编译器有关)。在某个时候,它会趁我们不注意,就出现一些意想不到的问题,比如:数组越界、空指针、数据库连接失败、内存溢出等。此时此刻的这些现象,就称为异常情况。
但是,计算机和人的最大区别之一,就是无论发生了多大的错误,计算机总会说得明明白白,为我们指明修复的大方向,而不需要各种各样的猜测。
异常总体分为两类,分别是非运行时异常和运行时异常。
非运行时异常,指的是在编译的过程中就已经出现的异常,一般idea会要求处理完之后,才能运行,所以这种很容易就能察觉。
运行时异常,指的是运行的时候出现的异常。一般要通过一些编程手段来处理,比如用try catch、对入参进行空判断等。
初学者在看到异常信息的时候,会十分慌张,天啊,为什么会报错?它说的什么意思?然后马上 Ctrl+CV 去网上疯狂找方案。其实,在遇到异常的时候,我们没有必要过于紧张,首先深呼吸一口气,一行一行地慢慢看,别着急。很可能只是配置没有配好、中英文符号问题、依赖冲突之类的,一系列常见问题。
针对异常的处理,常见的方案是捕获,或者抛出。捕获是在当前的方法进行处理,而抛出是丢给上一层或者上上层进行处理。就像背锅一样,是自己背,还是甩出去呢?看你自己咯。
接下来说说在面试中,如何扛住常见的几个问题。看到这里,请抬一下头,然后一鼓作气,把下面的重点看完。
1、说一说你是怎么理解异常的
这一类问题,可以先说说什么是异常,然后如何处理。
异常指的是程序可以处理的exception,应该尽可能地捕获,捕获后尽可能地恢复,而不应该随意终止。与异常相近的概念是error,error指的是程序无法处理的错误,一般是内存溢出、系统崩溃、虚拟机错误、方法调用栈溢出等JVM相关的问题,遇到的话只能让程序终止。
对于异常的处理,通常采用抛出异常或捕获异常的方式来处理,抛出异常指抛出一个Throwable对象或者是Throwable的子类对象,交由运行时系统处理;捕获异常指寻找合适的异常处理器来处理异常,否则终止运行。在捕获异常时,应该注意保留原始的信息,可以打印在日志里面保存起来,以便于定位问题并进行调试。
在程序运行的过程中,我们需要对异常进行统一处理,在Controller层,需要对各种自定义的业务异常进行统一拦截,返回给前端;在Service层,可以统一拦截数据库操作相关的异常,包装成自定义的业务异常向上抛;在全局层面,可以对其它未捕获的Throwable对象跟它的子类对象统一拦截,返回给前端。
2、异常有哪些种类
尽量说自己熟悉的、百分百对的出来,不熟的就不要硬抛书包了。
异常分为运行时异常RuntimeException和非运行时异常。非运行时异常,在编译阶段就能知道,而运行时异常,可以用程序来避免或者做一些补救措施,例如:先判断对象是否为空,再调用这个对象的方法,来避免空指针异常NullPointerException;常见的异常还有类型强制转换异常ClassCastException,传递非法参数异常IllegalArgumentException、下标越界异常IndexOutOfBoundsException、数字格式异常NumberFormatException
3、throw 和 throws 有啥区别?直接 try catch 不好吗,为啥还要抛呢
打开idea,自己敲两遍就知道啦。
throw是用在方法体内,主动抛出一个异常对象,而且只能抛一个,一般用在try/catch里面。throws用在方法声明后面,用来指定抛出一个或多个异常类型,让捕获者可以捕获或者处理这些异常。throw表示一定发生了某个异常,而throws表示可能会发生这些异常。有些异常不适合在当前方法中处理,而要抛给上层,让上层的调用者决定如何处理。例如:一个方法要读取一个文件,此时找不到这个文件,就抛出一个IOException,让上层调用者决定如何处理,例如重新选择一个文件或者提示用户错误信息,如果直接捕获了,可能无法通知调用者发生了什么问题,也无法让调用者有机会处理问题。
4、try catch会影响性能吗?
没有异常的时候,当然是皆大欢喜。一旦有人甩锅出去了,那问题就大咯。
如果try catch没有抛出异常,那么对性能几乎没影响,只是多了一些判断。但是如果try catch抛出了异常,对性能影响就很大,因为抛出异常需要做很多事情,例如:当一个异常被抛出,首先要创建一个异常对象,包含异常的类型、消息、栈信息等属性,需要占用内存空间;其次,要携带当前线程的调用栈信息,需要遍历当前线程的所有栈帧,并且将它们转换成字符串形式。然后JVM会寻找一个合适的异常处理器,来处理这个异常,需要匹配异常的类型和范围,从最近的栈帧开始向上查找,直到找到一个匹配的catch块或者到达栈顶。如果当前方法还有一些未完成的操作或者没有释放的资源,例如打开的文件流、持有的锁等,需要对这些资源进行清理,避免内存泄漏或者死锁
5、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗
finally就是最后的守护者,无论你做了什么,它都会为你兜底,为你负重前行。
finally的代码,无论前面是否有catch异常,都会执行的。如果catch和finally都有return,那么finally里面的return,会将catch的return覆盖掉。
今天的分享到这里结束了,如果你喜欢这种讲解知识的方式,欢迎下方留言。
你的支持,是我创作的最大动力!
关注公众号“徒手敲代码”,让我们在技术的星辰大海、生活的诗与远方中共勉同行,一起书写属于我们的精彩篇章!
猜你喜欢
- 2024-11-06 Java核心知识3:异常机制详解(java的三种核心机制是什么)
- 2024-11-06 【Spring系列】05 自定义异常以及全局异常处理器 #java
- 2024-11-06 3种Sentinel自定义异常,你用过几种?
- 2024-11-06 关于Java Exception异常的深入用法及实例
- 2024-11-06 Java-throw异常详解以及过程(java throw exception)
- 2024-11-06 《JAVA编程思想》5分钟速成:第12章(异常)
- 2024-11-06 面试官:java开发中异常怎么定义好 程序员:不知道
- 2024-11-06 「译」11条Java异常处理的最佳实践
- 2024-11-06 Java入门教程十一(异常处理)(java异常处理的三种方法)
- 2024-11-06 小白也能看懂的Java异常处理机制(java的异常处理机制的简单原理和应用)
你 发表评论:
欢迎- 05-16SpringBoot整合Redis实现常用功能
- 05-16基于Redis实现简单的延时消息队列
- 05-16安装Redis
- 05-16Spring系列之Redis的两种集成方式
- 05-16Django连接Redis集群问题排查思路和总结
- 05-16只需5分钟,完成Redis所有命令操作~
- 05-16熟练使用 Redis 的 5 大数据结构:Java 实战教程
- 05-16Redis 常见业务场景及实例(Java)
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)