从零开始学Java【22】

从零开始学Java【22】


​ 学习视频:https://www.bilibili.com/video/BV12J41137hu?p=77

什么是异常

image-20220510123139588

异常可以分为一下三大类:

image-20220510140222785

Java在设计出来的时候,就已经考虑过出现异常的几类问题,然后提出了异常处理框架的思想,即所有异常都可以用一个异常来表示。

异常体系结构

image-20220510140609170

Java把异常当作对象来处理,超类是所有类里面最底层的类,把所有的异常的类都囊括进去,所有的异常都是其子类。

如上图出现的各种异常,将来会学到当这些异常都出现的时候怎么把他们给捕获出来。

Error

image-20220510141316174

非运行时异常。这些错误在写代码的时候并不能觉察得到,尽量把环境调到最优从而尽量避免这些情况发生。

Exception

image-20220510141523080

运行时异常。这个异常是一些运行时的异常,与编程有关,是可以人为避免的。程序可以选择捕获,也可以选择不处理。

异常处理机制

image-20220510142906956

处理分为两步:一是抛出异常,二是捕获异常。直接上代码:

image-20220510144123113

上图是算数异常,使用try进行捕获异常:

image-20220510144314307

其中:

try方法体里面是监控区域,把有错的代码放进去,进行对这句话的监控,如果这句话有错,则使用catch捕获其异常。

catch的形参部分有:catch(捕获的异常类型 变量),错误类型输入执行try里面代码所显示的异常类型,也即第一张图中红框框出来的错误类型,这里的错误类型为ArithmeticException算数异常,然后变量随便命名为e,catch方法体执行出现上述异常之后执行的代码,这里输出一句话:程序出现异常,变量b不能为0

finally是作为收尾工作,即前面无论有没有出现异常,都会执行finally的方法体。finally可以不要,但是后面学到IO流,资源相关的需要关闭(比如Scanner这些东西),都可以把一些关闭的操作放到finally里面。

再来一个例子:

image-20220510145900497

其中StackOverflowError是捕获的异常类型。其实,可以用一个更厉害的类型来进行捕获:Throwable

image-20220510150556097

Throwable是超类,能捕获一切的程序错误,所以使用它没有问题。具体的可以看异常体系结构的那张图,只要比这个错误大的都可以放进去:

image-20220510151120350

除了捕获一个异常,其实也可以捕获多个异常,像if...else那样层层递进:

image-20220510151728078

对照上面的思维导图,可以发现Exception和Throwable都是其类型,而Error不是,首先执行第一个catch,不匹配就执行下一个catch,下一个满足了,执行完了就执行finally了,像if...else一样。

另外需要注意的问题是,从上往下的catch,里面的错误类型包含范围要从小到大,同级类型范围不相交则可以不分先后,比如下图:

image-20220510152058967

Throwable已经囊括了Exception,比Exception大,所以会报错。

另外需要注意的是,在try方法快,不能直接用【a();】因为静态方法不能调用非静态方法(main方法是静态方法,会报错)

image-20220510150759179

所以最好是new一个Demo01的对象出来,再调用对象的方法。或者把a或者b的方法都设置成静态的,这是静态与非静态的知识了。

选中当前代码,ctrl+alt+t

image-20220510153302845

image-20220510153743757

其中e.printStackTrace();为打印栈信息,可以看到自己的错误。

image-20220510155345943

除了上面try,catch,finally,还有关键词:throw和throws,名为主动抛出异常

上面的捕获异常程序还是会执行完成的,如果能预先预见一种错误,那我就可以选择主动抛出异常,这样程序就不用执行接下来的代码了,按照抛出异常给后的代码直接返回值。

  • throw。主动抛出异常,一般应用在方法里面,选择执行错误语句,有:

image-20220510162426047

显示异常。如果把错误语句注释掉,它还是会主动抛出异常:

image-20220510162246140

这就能起到防患于未然了。

  • throws。当某个方法可能会抛出某种异常时用于throws 声明可能抛出的异常,然后交给上层调用它的方法程序处理。

image-20220510163702941

可以看到,test这个方法并不能主动去解决这个异常,于是它选择“甩锅”,把这个异常抛出去,等待它的上层调用它的那些程序来进行处理。比如现在main方法里面就去调用了这个函数,把这个函数放进了try监控区域里面从而解决的。

生成try,catch快捷键

选中当前代码,ctrl+alt+t

小总结

  • throw是在方法里面的,而throws是在方法声明那里的
  • throw是在方法里面自己能解决的,throws是方法甩锅给其它调用它的程序来解决的。

参考文章:https://www.cnblogs.com/haoxiaonan/p/15660141.html

自定义异常

image-20220510164158019

一般这个很少用到,Java已经写出了很多异常,一般不去写大型框架或者是大型系统是用不到的。不过学一下还是可以的。

自定义异常类,只需要继承Exception即可。

image-20220510165845223

首先自定义一个类,类里面弄一个构造器,因为这里是大于10抛出异常,所以弄个有参构造器来定义属性值,作为外界传参能让这个类的属性有值。接着弄一个toString方法,用来打印异常。

以上这些先作为模板直接作为一个自定义异常。

然后main方法测试,传一个参数,主动抛出异常throw new MyException(a);

首先a>10,执行catch方法体,System.out.println("MyException=>"+e),而e其实就是异常的toString打印方法,打印"MyException{" + "detail=" + detail + '}',也就是输出界面的{detail=11}。

image-20220510171821918

这样就可以输出异常了。

总结

image-20220510172237297

posted @ 2022-05-10 17:29  机智的小柴胡  阅读(276)  评论(0)    收藏  举报