大家好,欢迎来到IT知识分享网。
难度
初级
学习时间
30分钟
适合人群
零基础
开发语言
开发环境
- JDK v11
- IntelliJ IDEA v2018.3
友情提示
- 本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。
- 本章内容针对零基础或基础较差的同学比较友好,可能对于有基础的同学来说很简单,希望大家可以根据自己的实际情况选择继续看完或等待看下一篇文章。谢谢大家的谅解!
1.异常体系
在Java异常这个大家族中,Throwable是这个异常家族中的老大,它下面有两个靠谱老弟,一个叫“Error”,一个叫“Exception”。Error老弟负责错误部门,Exception老弟负责异常部门,在Exception部门下面有一个特殊的弟弟,叫“RuntimeException”,RuntimeException负责运行时异常,它们各司其职。什么叫“运行时异常”?下一小节给大家解释,先看看它们的结构图:
红色部分就是RuntimeException(运行时异常)。可以看到它位于Exception的下面,属于Exception的子类。
Throwable在《“全栈2019”Java异常第十六章:Throwable详解》一章中已经介绍过了。
Error在《“全栈2019”Java异常第十七章:Error详解》一章中介绍过。
而Exception在上一章《“全栈2019”Java异常第十八章:Exception详解》中介绍过。
本章就来介绍RuntimeException。
2.运行时异常
“异常”这个词我们并不陌生,在Java异常系列文章的第一篇《“全栈2019”Java异常第一章:什么是异常?》中,我们就认识了异常。
那什么是运行时异常呢?
运行时异常是在Java虚拟机的正常运行期间可以抛出的那些异常。
不明白没有关系,我们来分词解释+举例说明。
“运行时异常是 在Java虚拟机的正常运行期间 可以抛出的 那些异常。”分为四组来看,分别是“运行时异常是”、“在Java虚拟机的正常运行期间”、“可以抛出的”和“那些异常”。
其中,“在Java虚拟机的正常运行期间”指的是JVM正常运行期间,通俗来说就是应用程序正常运行期间。“可以抛出的”指的是可以被throw的异常,只有Throwable及其子类才能被抛出,而RuntimeException就是Throwable的子类。
综上所述,运行时异常就是在应用程序运行期间抛出的异常。
这里我们再来一个例子感受一下。
演示:
请制造一个运行时异常。
请观察程序代码及结果。
代码:
Main类:
结果:
我们先不着急看结果,先看程序代码:
大家有什么发现没有?
程序内容是计算1除以0,但我们知道0不能被任何数除,所以程序运行到这里必定发生异常。既然会发生异常,为什么程序在运行前没有强制我们使用try-catch或throws处理呢?
因为运行时异常是“未检查的异常”,和“已检查的异常”不同的是,未检查的异常不需要强制try-catch和throws的,编译期间也不对其进行检查。所以上述程序代码可以编译通过,照常运行。
3.什么是检查?
这里小伙伴可能有疑问:“未检查的异常”和“已检查的异常”里面的“检查”是什么意思?
检查的意思就是看你对这些已检查的异常有没有进行try-catch或throws处理。
4.已检查的异常
那“未检查的异常”和“已检查的异常”分别是什么?
我们先来说说什么是已检查的异常?已检查的异常前面几章学习过,这里简单地来回顾一下,已检查的异常就是应用程序中可以预测和恢复的异常。
图中红色部分都是已检查异常。
比如其中的FileNotFoundException(找不到文件异常):
当发生FileNotFoundException异常时,我们可以对其try-catch处理,然后在catch代码块里面告知用户文件路径输入有误,请核对后再输入:
类似于FileNotFoundException这样的已检查的异常有很多,它们旨在帮助我们完善用户体验,增强程序的健壮性。
5.预测与恢复
“已检查的异常就是应用程序中可以预测和恢复的异常。”中的预测和恢复是什么意思?
预测:提前预知这里将会发生异常。
例如,这里可能发生文件不存在的情况:
恢复:对其发生的异常采取措施(try-catch或throws),使其程序正常运行。
例如,我们对将来可能发生的异常进行处理:
6.未检查的异常
那什么是未检查的异常呢?
对照已检查的异常,未检查的异常就是应用程序中无法预测和恢复的异常。
图中红色部分都是未检查异常。
Error及其子类和RuntimeException及其子类都是未检查的异常。
未检查异常有什么特殊之处吗?
未检查的异常在编译时乃至在运行时,都不需要你强制使用try-catch或throws对其处理。
例如,我们的算术异常ArithmeticException,下面程序只有在运行时才会发生异常:
实际开发中,我们接触到最多的未检查的异常就是RuntimeException及其子类。例如:ClassCastException(类型转换异常)和NullPointerException(空指针异常)。
7.RuntimeException
接下来,我们来看看RuntimeException类和它的子类们。
RuntimeException是所有运行时异常的父类。
图中红色部分都是运行时异常。可以看到有我们熟悉的算术异常ArithmeticException和空指针异常NullPointerException。
RuntimeException继承自Exception:
RuntimeException类里面的成员方法全部继承自父类,一个自定义的成员方法都没有,只有构造方法是自定义的:
我们把注释去掉再看看:
既然RuntimeException中的成员方法全部来自于父类,那么也就是说父类中的常用方法也就是我们RuntimeException中最常用的方法,之前在《“全栈2019”Java异常第十六章:Throwable详解》、《“全栈2019”Java异常第十八章:Exception详解》两章中讲解过它的父类Exception和Throwable常用方法,这里就不再赘述,请大家谅解。
抛出一个RuntimeException及其子类是我们实际开发中常用的做法,也是我们常常碰到的异常。比如ClassCastException(类型转换异常)和NullPointerException(空指针异常)。
8.类型转换异常ClassCastException
将对象强制转换为不是实例的子类就会发生类型转换异常。
上面这句话什么意思?
下面结合例子来解释说明。
演示:
请制造一个类型转换异常。
请观察程序代码及结果。
代码:
Main类:
结果:
错误信息:
文字版:
Exception in thread “main” java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader ‘bootstrap’)
at main.Main.main(Main.java:12)
我们先来看看程序代码,首先,我们创建一个变量i:
这个变量i的引用类型是Object:
变量i的实际对象是new Integer(0),对象的类型是Integer:
下面我们将变量i转换为String类型然后进行打印输出:
就在这时,程序发生了类型转换异常:
我们出错的根本原因就是我们将对象的类型Integer转换String,而Integer和String不是同一个类型,同一个类型指的是同一个类及其子类,什么意思?
比如,Integer类及其它下面的子类可以称为同一类型。String类及其它下面的子类也可以称为同一类型。但Integer和String不能称为同一类型。
我们再来将“将对象强制转换为不是实例的子类就会发生类型转换异常。”这句话结合例子来看。
“将对象强制转换为不是实例的子类”中的“对象”指的是new Integer(0):
“实例的子类”中的“实例”指的也是对象,也就是new Integer(0)。所以,“实例的子类”指的是Integer类及其子类。
综上所述,“将对象强制转换为不是实例的子类”这句话就是“将Integer强制转换为不是Integer类及其子类”,所以就发生了类型转换异常。
实际上,是不是这样的呢?
实际上就是这样的,我们将Integer转换为了String,而String不是Integer类及其子类。
类型转换异常在日常开发中很常见,希望大家把这个例子理解透彻,后面再解决类型转换异常就游刃有余。
9.空指针异常NullPointerException
当使用的对象为null时就会抛出NullPointerException。
例如下面这些情况。
调用null对象的实例方法
代码:
结果:
访问或修改null对象的字段
代码:
结果:
抛出的异常为null
代码:
结果:
还有很多触发NullPointerException异常的情况,这里就不一一列举了,但是它们都有一个共同的特征,那就是对象为null。
碰到NullPointerException该如何处理?
其实在实际开发中碰到NullPointerException,我们认为这些都是编程错误,应该手动排查错误,去修改。也就是说,不建议使用try-catch或者throws,建议手动查找出错的地方,更正程序代码。
好了,最后希望大家能够在日后的编程过程中少一些异常,多一些收获,谢谢大家的阅读。
总结
- 运行时异常是在Java虚拟机的正常运行期间可以抛出的那些异常。
- 运行时异常就是在应用程序运行期间抛出的异常。
- 检查的意思就是看你对这些已检查的异常有没有进行try-catch或throws处理。
- 已检查的异常就是应用程序中可以预测和恢复的异常。
- 未检查的异常就是应用程序中无法预测和恢复的异常。
- Error及其子类和RuntimeException及其子类都是未检查的异常。
- 未检查的异常在编译时乃至在运行时,都不需要你强制使用try-catch或throws对其处理。
- RuntimeException是所有运行时异常的父类。
- 实际开发中,我们接触到最多的未检查的异常就是RuntimeException及其子类。例如:ClassCastException(类型转换异常)和NullPointerException(空指针异常)。
- 将对象强制转换为不是实例的子类就会发生类型转换异常。
- 当使用的对象为null时就会抛出NullPointerException。
- 其实在实际开发中碰到NullPointerException,我们认为这些都是编程错误,应该手动排查错误,去修改。也就是说,不建议使用try-catch或者throws,建议手动查找出错的地方,更正程序代码。
至此,Java中运行时异常RuntimeException相关内容讲解先告一段落,更多内容请持续关注。
答疑
如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。
上一章
“全栈2019”Java异常第十八章:Exception详解
下一章
“全栈2019”Java异常第二十章:自定义异常
学习小组
加入同步学习小组,共同交流与进步。
- 方式一:关注头条号Gorhaf,私信“Java学习小组”。
- 方式二:关注公众号Gorhaf,回复“Java学习小组”。
全栈工程师学习计划
关注我们,加入“全栈工程师学习计划”。
版权声明
原创不易,未经允许不得转载!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/85122.html