异常
在程序的执行过程中,程序出现了一些问题(Bug).
异常的体系结构
Throwable Java 语言中所有错误或异常的父类
两个子类:
- Error:严重问题(一些其他原因导致的) :需要借助于第三方技术解决
比如: 内存溢出(Out Of Memeory) - Exception: 不是很严重问题(程序出现代码不严谨或者一些编译问题)
比如:运行时期异常:RuntimeException
举例:ClassCastException/NullPointerException/ArrayIndexOutOfBoundsException
运行时期出现的原因:开发者编码的时候,代码逻辑不严谨!
编译时期异常原因:jvm在检查语法的时候,针对某些特定的方法针对方法进行判断,如果不解决编译时期异常,程序执行不了的!
编译时期异常:只要不是RuntimeException的子类都属于编译时期异常
ParseException(属于编译时期异常)
异常的处理方式
一般开发中常用:捕获异常 try…catch…finally :标准格式
-
throws/throw:抛出异常
方式1:捕获异常
try...catch...finally :标准格式
变形格式:
1)try...catch...
2)try...catch...catch...
3)try...finally... (多线程中见到)
try{
可能出现问题的代码 ;
}catch(异常类名 变量名){
处理异常 ;
}
方式2
直接在方法声明上抛出异常。
如何处理多个异常
1)一个一个处理
每一个代码都try…catch…
try…catch…
2)变形格式(推荐)
try…catch…catch…catch…
注意事项:
针对多个异常处理的时候,只能大的异常类名放在最后面进行处理,不能放在最前面
JDK7以后:有一种的新的处理方式: (源码里面会看到,看懂格式即可)
try{
可能出现的代码;
}catch(异常类名1 | 异常类名2 | 异常类名3 变量名){
处理异常;
}
编译时器异常和运行时期的区别?
-
编译时期异常:开发者必须要处理,否则编译不通过,程序运行不了!
调用者必须针对编译时期的异常进行处理(在方法体中使用的捕获异常,调用者不需要处理;如果是将异常抛出在方法声明上,调用者需要处理) -
运行时期异常:
一般情况,针对代码可以不需要显示处理,在代码中加入一些逻辑判断
1)要么显示处理
2)要么代码中加入一些判断即可!
面试题
throws和throw的区别?
1)位置不同
throws是在方法声明上抛出
throw:是在方法体(语句)中抛出
2)两个关键字后面的跟的类型不一样
throws后面跟的是异常类名,而且可以跟多个异常类名,中间使用逗号隔开;
throw后面跟的异常对象名(匿名对象),throw new xxxException();不能跟多个异常对象,只能跟一个!
3)throws表示产生异常的一种可能性!
throw:表示产生异常的一种肯定性!
4)throws抛出的异常由他的调用者进行处理
throw:方法中的语句进处理(加入一些逻辑判断)
异常使用的注意事项
1)子类继承父类的时候,如果父类的该方法本身就存在异常,那么子类重写父类该方法的时候 必须是该异常或者是异常的子类 (简单记:父亲坏了,儿子不能比父亲还坏)
2)子类继承父类,父类的成员方法如果没有当前异常,子类不能抛出throws,只能try…catch
- 捕获异常的格式
try{
可能出现问题的代码;
}catch(异常类名 变量名){
处理异常;
}finally{
在IO流中/JDBC中释放相关的系统资源;
}
finally中的语句一定会执行,除非是在执行finally代码之前,jvm退出了!
面试题
- 在try…catch…finally中,catch中如果有return语句的话,finally中代码还会执行吗? 如果会,在catch之前,还是catch之后?
(finally中的语句一定会执行,除非是在执行之前,jvm终止了,才不会执行!)
答:会执行,在执行finally语句之前,方法已经形成回路径,具体在执行前就已经返回了(catch和finally之间就返回结果了);