在程序发生异常的时候,如果没有任何地方进行捕获,程序就不能执行下去,会在控制台打印异常信息,所以就产生了捕获异常。也就是try/catch语句块。
Try里面内容发生的异常能被捕获,同时发生异常后,在try块里发生异常的语句后面的语句将不再执行,同时要注意catch抓异常,必须要匹配的异常的才能捕获,不匹配只能向上层调用者进行抛出。同时要注意finally语句一定会执行,不论try中的情况如何,这也是为什么会经常在finally中关闭资源。
同时在捕获异常的时候,能够使用多个catch语句进行捕获不同类别的异常,方便针对不同异常进行不同的处理。同理如果是同一个处理方式,就可以在catch语句中使用”|”抓取多个异常。同时如果异常有包含的情况,语句写在前面的会先抓住异常,后面的就抓捕不到异常了。如下图
讲到异常就要提到再次抛出异常和异常链,这是一个非常不错的设计。如果我抓到了异常,但是我不想让上层看到这个原始异常,我可以自己加工包装异常再抛出去,同时把详细异常的信息也放在其中,方便要知道的时候能够找到异常的真正原因,而不是一个大概。当然了这个异常类需要自己定义的。这里举了个例子。这将非常有用,在我们实际编程时候,不想让上层直接看到出错的信息,就可以告诉上层,是下层的某个地方出现了异常,并将异常的详细信息放在这个异常的的一个属性中返回给上层,相当于给异常穿上了一层外套,这将是非常友好的编码。
接下来聊聊finally语句,finally语句主要作用就是清除分配的资源,如数据库,文件流的关闭。Finally是一定会执行的,跟有没有return是没有关系的。这里书上也给出过建议,使用如下图方式来抓住所有的异常。
最后要注意一种返回值覆盖的情况。也就是finally 或者在抓住异常的情况下,catch模块中重新赋值的情况下会覆盖原来的值。也可以这么理解,就是刚开始的return并没有真的return,会等到执行完后才能return内容,而这个内容又会被其它覆盖。同时也要注意异常的抛出同样能覆盖,如果finally中的异常抛出了异常就会覆盖原来抛出的异常。
带资源的try语句,可以最后不用关闭资源,这是因为资源实现AutoCloseable接口,在退出try块的时候能自动关闭资源。