从零开始学Java【22】
从零开始学Java【22】
 学习视频:https://www.bilibili.com/video/BV12J41137hu?p=77
什么是异常

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

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

Java把异常当作对象来处理,超类是所有类里面最底层的类,把所有的异常的类都囊括进去,所有的异常都是其子类。
如上图出现的各种异常,将来会学到当这些异常都出现的时候怎么把他们给捕获出来。
Error

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

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

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

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

其中:
try方法体里面是监控区域,把有错的代码放进去,进行对这句话的监控,如果这句话有错,则使用catch捕获其异常。
catch的形参部分有:catch(捕获的异常类型 变量),错误类型输入执行try里面代码所显示的异常类型,也即第一张图中红框框出来的错误类型,这里的错误类型为ArithmeticException算数异常,然后变量随便命名为e,catch方法体执行出现上述异常之后执行的代码,这里输出一句话:程序出现异常,变量b不能为0
finally是作为收尾工作,即前面无论有没有出现异常,都会执行finally的方法体。finally可以不要,但是后面学到IO流,资源相关的需要关闭(比如Scanner这些东西),都可以把一些关闭的操作放到finally里面。
再来一个例子:

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

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

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

对照上面的思维导图,可以发现Exception和Throwable都是其类型,而Error不是,首先执行第一个catch,不匹配就执行下一个catch,下一个满足了,执行完了就执行finally了,像if...else一样。
另外需要注意的问题是,从上往下的catch,里面的错误类型包含范围要从小到大,同级类型范围不相交则可以不分先后,比如下图:

Throwable已经囊括了Exception,比Exception大,所以会报错。
另外需要注意的是,在try方法快,不能直接用【a();】因为静态方法不能调用非静态方法(main方法是静态方法,会报错)

所以最好是new一个Demo01的对象出来,再调用对象的方法。或者把a或者b的方法都设置成静态的,这是静态与非静态的知识了。
选中当前代码,ctrl+alt+t


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

除了上面try,catch,finally,还有关键词:throw和throws,名为主动抛出异常
上面的捕获异常程序还是会执行完成的,如果能预先预见一种错误,那我就可以选择主动抛出异常,这样程序就不用执行接下来的代码了,按照抛出异常给后的代码直接返回值。
- throw。主动抛出异常,一般应用在方法里面,选择执行错误语句,有:
 

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

这就能起到防患于未然了。
- throws。当某个方法可能会抛出某种异常时用于throws 声明可能抛出的异常,然后交给上层调用它的方法程序处理。
 

可以看到,test这个方法并不能主动去解决这个异常,于是它选择“甩锅”,把这个异常抛出去,等待它的上层调用它的那些程序来进行处理。比如现在main方法里面就去调用了这个函数,把这个函数放进了try监控区域里面从而解决的。
生成try,catch快捷键
选中当前代码,ctrl+alt+t
小总结
- throw是在方法里面的,而throws是在方法声明那里的
 - throw是在方法里面自己能解决的,throws是方法甩锅给其它调用它的程序来解决的。
 
参考文章:https://www.cnblogs.com/haoxiaonan/p/15660141.html
自定义异常

一般这个很少用到,Java已经写出了很多异常,一般不去写大型框架或者是大型系统是用不到的。不过学一下还是可以的。
自定义异常类,只需要继承Exception即可。

首先自定义一个类,类里面弄一个构造器,因为这里是大于10抛出异常,所以弄个有参构造器来定义属性值,作为外界传参能让这个类的属性有值。接着弄一个toString方法,用来打印异常。
以上这些先作为模板直接作为一个自定义异常。
然后main方法测试,传一个参数,主动抛出异常throw new MyException(a);
首先a>10,执行catch方法体,System.out.println("MyException=>"+e),而e其实就是异常的toString打印方法,打印"MyException{" + "detail=" + detail + '}',也就是输出界面的{detail=11}。

这样就可以输出异常了。
总结

                    
                
                
            
        
浙公网安备 33010602011771号