7.1 异常理解
- 概念:程序运行过程中发生的不正常情况。
7.2 异常的体系结构
- Error:Java虚拟机无法解决的严重问题。一般不做处理。
- StackOverflowError:栈溢出
- OutOfMemoryError(OOM):堆溢出
- Exception:
- 编译时异常:
- 运行时异常:
7.3 异常处理机制
7.3.1 抓抛模型:
- "抛":程序执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并会将此对象抛出给调用它的方法,直到main方法,如果main方法没能处理,则程序运行终止,发生异常位置后面的代码也不会执行。
- 异常产生有两种形式:一是系统自动产生,二是手动生成并抛出(throw)
- "抓":即异常的处理方式:
- try-catch-finally
- throws
7.3.2 try-catch-finally
- 语法:
try{ ...... //可能产生异常的代码 } catch( ExceptionName1e ){ ...... //当产生ExceptionName1型异常时的处置措施 } catch( ExceptionName2e ){ ...... //当产生ExceptionName2型异常时的处置措施 } [ finally{ ...... //无论是否发生异常,都无条件执行的语句} ]
- try不能单独使用
- catch和finally是可选的。
- try-finally:没有catch语句,相当于捕获到了异常但没有处置,会先输出finally中的语句,再报异常,程序也会中止。
- try-catch-finally:先报异常,再输出finally语句,程序不会中止
- 在try结构中声明的变量,出了try结构以后,就不能再被调用
- try-catch-finally结构可以嵌套
- 使用:IDE快捷键: 选中->ctrl + alt + t
- 执行流程:
- 如果异常没有发生,则顺序执行try的代码块,不会进入到catch。
- 如果异常发生了,则异常发生后try块中的代码不会执行,直接进入到catch块。执行完catch块后再执行try-catch语句后的代码。
- 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用finally
- 即使try、catch语句里有return(正常情况return结束方法),执行完之后仍然会执行finally中的语句,再返回结束方法。但当finally中有return语句,则不再执行try或catch的return。
- 可以使用多个catch分别捕获不同的异常,要求子类异常写在前面,父类异常写在后面
- try中有多个异常,且父类一致(如Exception),如果catch只匹配父类,则只捕获第一个异常,try中后面的代码(所有代码)不会被执行
- try中有多个异常,catch匹配多个异常,但只捕获第一个异常,try块中后面的代码(所有代码)不会被执行,异常也不会捕获到
- 常用的异常对象处理的方式:
- getMessage() :打印异常信息
- printStackTrace(): 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
7.3.3 throws + 异常类型
- "throws + 异常类型"写在方法的声明处,指明此方法执行时,可能会抛出的异常类型。
- 抛出多个异常使用
,
分隔
- 一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。不满足则相当于异常没有处理。异常代码后续的代码,就不再执行!
- throws的方式只是将异常抛给了方法的调用者。并没有真正将异常处理掉,方法调用者再抛出时,异常类型要不小于接收到的异常类型。
- 运行异常的默认处理方式为throws,可不处理,编译异常没有默认处理方式,必须处理
- 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型
- 在throws 过程中,如果有方法 try-catch , 就相当于处理异常,就可以不必throws
7.4 try-catch-finally和throws的选择
- 拥有继承关系的父子类,如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中有异常,必须使用try-catch-finally方式处理。
- 执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。建议这几个方法使用throws的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
7.5 手动抛出异常
- 在可能发生异常的位置生成异常类对象,然后通过throw语句实现抛出操作
- 可以抛出的异常必须是Throwable或其子类的实例,否则会报错。
7.6自定义异常类
- 继承于现有的异常结构:RuntimeException 、Exception
- 继承exception时为编译异常
- 一般使用RuntimeException,且需要方法再thows异常
- 提供全局常量(static final修饰):serialVersionUID
- 提供重载的构造器,传入
String msg
参数 - 构造器内执行
super(msg);