概述
目录
异常处理
异常不是语法错误
异常在表现形式上分两种:
1、运行时异常
2、编译时异常
在Java中异常的设计
1、异常的分类
2、异常的传播机制
异常的解决方案
运行时异常
try-catch-finally
编译时异常
throw和throws
异常处理
异常不是语法错误
首先我们得明白,异常不是语法错误。
int a = 3.14;
对于这样一个错误的变量声明,你是无法用try-catch救回来的,因为这是语法错误。
异常在表现形式上分两种:
1、运行时异常
语法没有错误,编译通过了,但是运行起来后程序在控制台报错,并停止运行。
2、编译时异常
所谓编译时异常。即语法没有错误,但是编译不通过。用鼠标指过去以后,会提示:有未处理的异常,后面跟异常的名字。
在Java中异常的设计
异常处理是Java中保证健壮性的手段,它有自己的设计。
1、异常的分类
在Java编程中可能出现的各种异常类型都有见名知意的名字。
- NullPointerException
空指针异常 --- 企图调用一个空对象的属性或方法
- ArrayIndexOutofBoundsException
数组下标越界异常
- ClassCastException
类型转换异常
这么多异常类,形成了一个树形结构图。
最顶级的:Throwable类
第二级: Exception Error Exception -- 异常 Error -- 错误 他们都是我们程序在语法正确的情况下,在运行期或编译期出现的问题。但是两者的严重层度和解决方案不一样。
Exception更多的是指可以用代码去解决的问题; Error往往不是代码级别的问题,往往是运行环境或硬件问题。
Exception和Error都是Throwable的子类,所以他们都可以抛出,当然也都可以catch。
第三层:Exception的子类 RuntimeException --- 它和它的子类是运行时异常;--- 也就是在编译期不检查是否处理,没处理的话运行时报错。
非RuntimeException --- 它们和它们的子类是编译时异常;--- 要求编译期必须解决,否则编译不通过。
2、异常的传播机制
首先要会认知报错信息,要能够从中获取正确的有帮助的信息:
2-1、如错误发生在哪个线程当中
2-2、发生了什么异常 --- 看异常的名字
2-3、发生在哪里? --- 从上往下翻看错误信息
为什么会有多个异常发生位置? 这是因为异常的传播机制。在程序运行阶段,一旦发生了异常,那么JVM会自动产生一个对应类型的异常对象,把本次发生异常的基本信息封装进去。然后在当前代码处,查看是否有该异常的处理方案;如果没有,那么JVM会提前结束这个方法,然后带着异常对象返回方法调用处。接着,在方法调用处查看是否有该异常的处理方案,如果没有,那么再结束这个方法,返回它的调用处。如此执行下去,直到main方法如果也没有解决,那么终止main方法,打印异常信息在控制台。而main方法的终止,程序肯定也终止了。
异常的解决方案
运行时异常
1、通过提前判断,把异常扼杀在摇篮中
2、逻辑错误,修改代码
3、try-catch
try-catch-finally
1、try的含义就是试,所以在try块中就是书写有可能发生异常的代码块,我们试着让它去执行;
2、try不能够单独存在的,后面必须跟上catch 或 finally;同样catch和finally也是不能单独存在的,必须配上try;
3、catch的含义就是捕获,catch的圆括号中是表明我们要捕获哪种异常;花括号是用来确定捕获住以后,要做什么。
在catch的圆括号当中,就是一个异常变量的声明;然后一旦发生异常,执行进入catch块,就会拿这个变量去匹配(instanceof)JVM产生的异常对象。匹配上说明这个catch块就是处理这个异常的,没有匹配上,说明这个catch块不是处理它的。
【注意】:只要匹配上,那么这个异常就算是被抓住了,就不会继续往上传播,程序回到正确逻辑执行。
4、如果在try的代码中,可能出现多种异常,那么后面是可以接多个catch块的,每个catch捕获一种。 一个try块内部可以有多种异常,但每次只会发生一种,然后停止执行try剩余代码,然后从上往下依次匹配每个catch块,谁匹配住了进入谁内部,然后执行完catch,跳到最后面去。 如果同时有多个catch块,那么这多个catch捕获的exception如果有继承关系,那么必须是先捕获子类,再捕获父类。如果捕获的多个exception没有继承关系,那么谁先谁后就没有关系了。
5、finally块是用来书写不管是否发生异常,都必须要执行的代码。往往是:资源的回收,清理动作。
编译时异常
两种解决方案:
1、try-catch;
2、throws;
它的存在主要是一个异常到底该谁处理的职责问题。因为底层代码中有一些初始条件来自于外部的调用者(传参),这个数据的正确性不是由底层方法的实现者来控制的。因此如果由这个数据的正确性出现了问题,那么就不应该由底层这个使用者来进行处理,必须通知调用者去检查,从而才设计了抛出这么一个机制的存在。
抛出机制并没有处理异常,仅仅是在编译期强制调用者通过语法去检查明确自己的传入的数据对不对。
throw和throws
1、throw 位置:throw是写在方法内部的 后面接的内容:throw后面接的是一个异常对象 代表的含义:运行期,throw语句被执行的时候,是会真正发生抛出一个异常对象。
2、throws 位置:throws是写在方法声明(签名)的最后 后面接的内容:throws后面接的是一个或多个异常类的类名 代表的含义:编译期,用来警告方法的调用者,本方法有可能会发生某些类型的异常,你要做处理。
3、两者的关联 在语法上,如果throw的是一个运行时异常,那么不强制要求写throws;但是如果是一个编译时异常,那么必须写throws。
【总结】
1.对于编译时期出现的报错,多是由语法错误造成的。
2.对于控制台出现的报错信息,要会认知报错信息,能够从中获取正确的有帮助的信息,对于代码的书写逻辑有极大帮助
最后
以上就是隐形睫毛膏为你收集整理的关于Java中异常的处理【干货篇】异常处理的全部内容,希望文章能够帮你解决关于Java中异常的处理【干货篇】异常处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复