第8天的笔记(异常)

来源:互联网 发布:中国老师来了 知乎 编辑:程序博客网 时间:2024/06/06 10:47

   本来打算将异常一章结束掉,不过时间不够了(临近11:30),只能看到哪算哪,发了再说。明天补之,并开始新的一章——封装类。

2011-05-23(Exception)
1、异常的传播。异常是一个对象,某个方法(A)出现异常,这个异常会传递给调用这个方法的方法(B),这个方法有会把异常传递给调用它的方法(C),如此向上传递,知道main方法。即异常传递为:A—>B—>C—>main。注意,每个方法(包括main方法)接受到异常后都会抛出异常,这种现象称为异常再抛出。如下面代码:
编译成功,运行结果为:
                      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
                       at Test.A(Test.java:16)
                       at Test.B(Test.java:11)
                       at Test.C(Test.java:7)
                       at Test.main(Test.java:3)
第十六行,数组下标溢出,产生数组下标越界异常,之后就层层传递。另外,由异常后面的代码:“System.out.println("OK");”无法进行,可看出java的代码执行顺序:先执行main,里面需调用C,执行C,里面需调用B,执行B,里面需调用A,执行A,A里面出现异常,之后往回传递。
2、如果将代码改为如下:
  结果是:
                                                         Catch successed
                                                         OK4
                                                         OK2
                                                         OK1
从“OK”的打印顺序看,异常往回传递到B方法,被捕获后B就想没发生异常一样照常进行,而后面的C、main也照常进行,所以按执行的顺序打印了“OK4”“OK2”“OK1”。
3、将2代码第17行改为a[2]=1;即不出现异常。编译执行,结果为“OK5OK3OK4OK2OK1”,catch里面的语句没有执行。从这里和2可以看出:当出现异常,try里面代码不执行,如果没有try,更加是整个程序都不执行;如果没有异常,catch里面语句不执行。但是某种情况下,我想有无异常都要执行某段代码,当如何?(或者某人会钻牛角尖,说把这段代码往try、catch都放上即可。先不说这段必须执行的代码很长导致可读性差的问题,如果是try里面抛出了意料之外的异常呢,亦是不可)所以,必须有finally关键语句块用以放无论是否有异常都要执行的语句。当然,如下情况是不能执行finally里面的语句的:
(1)finally本身有异常;
(2)执行finally语句块地线程死亡;
(3)finall中执行了System.exit(0);
(4)断电;
4、try、catch、finally之间要注意的问题:
(1)catch必须紧跟try,同理,在没catch情况下,finally也必须紧跟try;
(2)上面提到,catch、finally均可省略,但不可同时省略,即不能单有try语句;
(3)try、catch、finally之间必须没有任何代码,注释除外。
5、Exception类的子类中,除去RuntimeException类及其直接或间接子类,都称之为捕获异常,即必须处理的异常。如果写代码是不对塔进行处理,编译会出错。另外,如果try里面的不可能抛出某种捕获异常,catch又编写了该捕获异常的处理代码,编译也会出错。
6、除了捕获异常,其他的异常都成为未捕获异常(Error类和Exception类及其子类),即不用必须处理异常。上面的数组下标越界异常属于此类,编译没错,运行会抛出这类异常。
7、再抛出异常的分类——分显现再抛出和隐形再抛出。
I、一旦某个方法可能会抛出捕获异常,则在方法声明之时必须特别指出。而通过编写代码将catch语句捕获的异常再次抛出,称显性再抛出。特别指出的语法:
                                  访问限制 [static] 返回在类型 方法名(参数列表)
throws 异常序列
这个异常序列,每个异常之间用逗号隔开。对于捕获异常必须列出,未捕获异常,可列可不列。catch中,通过语法:
                                                     throw 异常对象的引用
将异常再抛出,throw只能跟一个异常对象的引用,注意这里的用词,是对象的引用,并且这个引用类型的决定了再抛出异常的类型,而非引用指向的对象。
II、上面的1,也是再抛出异常,并无throws语句,编译也通过,这是为何?因为那是隐性再抛出,其与显性有如下异同:
(1)若在抛出的异常是捕获异常,则隐性、显性都必须在方法题中声明;
(2)显性再抛出是在方法体中使用throw语句抛出;
(3)隐性再抛出是在方法体中无任何抛出语句,若产生则自动抛出。
8、方法重写中的抛出异常。子类重写父类方法时,重写后的方法所抛出的异常范围必须小于等于父类的。等于好理解,就是抛出的异常类型与父类同;小于,就是重写后的方法抛出的异常是父类抛出异常的子类。


 

原创粉丝点击