Java异常

Java异常就是在一些情况下,程序报错,这就是报异常,告诉我们这个程序哪里出了什么样的问题.

如下图:

这就是一个异常,java.lang....就是异常的种类,后面跟的这个异常叫做算数异常,后面会跟着一个原因,为什么出这个异常,再下边就是在第几行出现的异常,

我们点进去这个异常的类型中可以看见

其实这个就是一个类,异常有很多种,这个是其中的一种

如上图,这也是一个异常,这个整形数组是null,也就是说这个数组不指向任何的对象,在我们打印它的长度的时候也会抛出一个异常叫做空指针异常,当没有处理这个异常的时候,程序会到此为止,然后抛出一个异常.

以上这几种异常是比较常见的额异常,上边的异常叫做数组越界异常,因为数组里只有4个元素,没有10这个下标.

异常的分类

异常分为编译时异常(受查异常),运行时异常(非受查异常),受查异常就是在编译时期可以检测出来的,非受查异常就是在编译的时候不能检测出来的异常.

比如我现在要写一个clone的方法,去克隆这个person类,这个类实现了这个克隆的接口,重写了clone的方法,但是现在还是报错的,所以从时期上来分,这个异常就属于编译时的异常(受查异常),因为还没运行呢,这个clone就报错了,所以这个就是受查异常.

可以看到,异常就是类-->throwable这个类的子类有error和exception,error是错误,exception是异常,

可以看到,当我无条件们递归循环调用func方法的时候,这个报错就是显示error,error代表这个错误是一个Java虚拟机无法解决的问题,这是一个逻辑上的错误,需要程序员手动排查的.

而exception是异常产生后,程序员同构代码的处理,让程序继续执行,

还有exception,它的子类有IOException和RuntimeException,就是受查异常和非受查异常,比如算数异常,空指针异常等等就是运行时异常(非受查异常),

异常的处理

要处理异常,首先要有异常:1.程序执行的过程中,自己抛出了异常, 2.自己手动设置模拟抛出异常.

上图就是我自己手动抛出一个异常,下面java:12 代表指定了直接抛出异常的位置,16代表出现的异常,一般的,如果上面的问题解决了,下面的就没问题了,一般用在自己自定义的异常.

如上图,这就是程序自己运行的时候抛出的异常.

如果抛出的是受查异常(编译时异常),需要我们手动去处理.

如果抛出了异常,程序就不再向下执行了.

throw必须写在方法体内部

异常的捕获

这个就是第一种具体处理异常的方式,当我们不写throws CloneNotSupportedException的时候,这个就会报错(受查异常),它需要我们手动处理异常,加的这句话就相当于当我在使用这个方法的时候,这个方法就告诉我,你使用这个方法,会抛出一个什么什么样的异常.

此时的这种方法去处理异常只是不报错了,当我们去执行这个程序的时候依然会抛出异常,如下图:

此时的声明只是为了让程序在编译的时候不进行报错了,下面打印fsfe的语句仍然不会执行.

所以说当我们没有真正的处理某种异常的时候,我们就会把异常交给jvm,一旦交给jvm之后,程序就崩溃了.

其实这个问题不大,但是就终端执行了,所以说这种方法是比较粗暴的,所以还有一种方法,可以解决当我们不想让程序中断运行的情况下,程序可以继续执行.

此时就用到了trycatch语句:

此时可以看到正常的逻辑在执行,catch语句种写处理异常的逻辑,处理完成之后,让程序继续执行,这个时候没有把异常交给jvm处理,才真正的处理了异常,catch语句可以写一个,也可以写多个.

这个地方报错的原因是当我们抛出受查异常的时候,此时检测不到就会报错.

当try种存在多个异常的时候,从上往下执行,谁先抛出异常,就捕获哪一个异常,和下面写的捕获的顺序没有关系.

如果try中存在的异常没有在catch中及时捕获,就会交给jvm处理,一旦交给jvm处理,这个程序就会崩溃,不会执行下面的语句了.

如果异常具有父子类的关系,要把子类异常放在前面,父类放在后面,因为子类的异常父类也可以捕捉到,那子类的存在就没意义了.

finally

finally的使用是在捕捉到异常之后,不管是否捕捉到了异常,都会去执行finally语句.

可以看到,不管是否捕捉到了异常,finally语句都会被执行,所以finally语句一般用于资源的释放,

上图展示了finally可以用来关闭资源,scanner也是一个资源,文件也是一个资源.finally总会被执行到,所以可以关闭上面消耗的资源,进行资源回收.

throw和throws的区别:throw用来抛出异常,throws用来声明异常.

还有不建议将return写到finally中,因为会把上边的return给覆盖掉.

异常处理的流程

这个流程是按照调用栈走的:

程序先执行try中的代码

如果try中的代码出现异常,就结束try中的代码,看try中的异常和哪一个catch匹配

如果找到匹配的异常类型就执行catch中的代码

如果没有找到匹配的catch类型,会将异常向上传递,也就是说比如在func方法中出现的异常,但是没有在func中处理这个异常,在main方法中调用了func方法,就需要在main方法中去处理这个异常

如果main方法中也没有处理这个异常,就 会交给jvm去处理,这个时候程序就会中断运行.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良月初十♧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值