异常类
Java中处理异常的两种方式
- 捕获异常:就地解决,并使程序继续执行
//积极的处理方式
当Java运行时系统得到一个异常对象时,他将会沿着方法的
调用栈
逐层回溯,寻找处理这一异常的代码。找到能够处理这种类型的异常的方法后,运行时系统把当前的异常对象交给这个异常方法后,这一过程称为捕获(catch)异常。如果Java运行时系统找不到可以捕获异常的方法,则运行时系统中将终止,相应的Java程序也将退出。 - 声明抛弃异常:将异常抛出方法之外,由调用该方法的环境去处理
//消极的处理方式
如果在一个方法中生成了一个异常,但是这一方法并不确切地知道该如何对这一异常事件进行处理,这时,一个方法就应该声明抛弃异常,使得异常对象可以从调用栈向后传播,直到有合适的方法捕获它为止。
Java中预定义的异常类
Error
Error标识不可能或难以恢复的严重问题,例如内存不足,程序一般不处理这类情况。
RuntimeException
RuntimeException指示设计或实现上的问题,如果程序正确运行,这样的情况是不应该出现的。
常见异常
- NullPointException–空指针异常
- ArrayIndexOutOfBoundsException–数据越界异常
- NegativeArraySizeException–数组负下标异常
- ArithmeticException–算数异常类
- ClassCastException–算数运算异常
- IllegalArgumentException–传递非法参数异常
- ArrayStoreException–向数组中存放与数组类型不符元素异常
- NumberFormatException–数字格式异常
- SecurityException–安全异常
- UnsupportedOperationException–不支持的操作异常
try-catch语句
12345678910111213141516171819try{//打开文件//判断大小//分配内存//读入内存//关掉文件}catch(/*文件打开失败*/){//处理代码}catch(/*大小取值失败*/){//处理代码}catch(/*内存分配失败*/){//处理代码}catch(/*读取失败*/){//处理代码}catch(/*关闭文件失败*/){//处理代码}finally{//总是执行的代码,即使碰到return也执行finally后才return,除非遇到System.exit(),程序会立刻退出}
throw/throws抛出异常
|
|
堆栈调用机制
- 如果一个try-catch块中没有处理,那么将会抛向此方法的调用者
- 如果一个异常回到main方法,而且也没有处理,那么程序终将终止
自定义异常类
12345678910111213141516171819202122232425262728public class MydateException extends Exception{private String reason;public MydateException(String r){reason = r;}public String getReason(){return reason;}}public class Mydate {int year,month,day;void setDate(int year,int month,int day) throws MydateException{if(day>31)throw new MydateException("day too big");this.year = year;this.month = month;this.day = day;}public static void main(String[] args){Mydate t = new Mydate();try {t.setDate(2001,1,100);}catch (MydateException e){System.out.println(e.getReason());}}}
问答题 :
问:请简单描述下面方法的执行流程和最终返回值是多少?
答:本题旨在考察 try-catch-finally 块的用法踩坑经验,具体解析如下。
test1 方法运行返回 0,因为执行到 try 的 return ret; 语句前会先将返回值 ret 保存在一个临时变量中,然后才执行 finally 语句,最后 try 再返回那个临时变量,finally 中对 ret 的修改不会被返回。
test2 方法运行返回 2,因为 5/0 会触发 ArithmeticException 异常,但是 finally 中有 return 语句,finally 中 return 不仅会覆盖 try 和 catch 内的返回值且还会掩盖 try 和 catch 内的异常,就像异常没有发生一样(特别注意,当 finally 中没有 return 时该方法运行会抛出 ArithmeticException 异常),所以这个方法就会返回 2,而且不再向上传递异常了。
test3 方法运行抛出 hello 异常,因为如果 finally 中抛出了异常,则原异常就会被掩盖。
因此为避免代码逻辑混淆,我们应该避免在 finally 中使用 return 语句或者抛出异常,如果调用的其他代码可能抛出异常,则应该捕获异常并进行处理。
问:如果执行 finally 代码块之前方法返回了结果或者 JVM 退出了,这时 finally 块中的代码还会执行吗?
答:只有在 try 里面通过 System.exit(0) 来退出 JVM 的情况下 finally 块中的代码才不会执行,其他 return 等情况都会调用,所以在不终止 JVM 的情况下 finally 中的代码一定会执行。
问:java 中 finally 块一定会执行吗?
答:不一定,分情况。因为首先想要执行 finally 块的前提是必须执行到了 try 块,当在 try 块或者 catch 块中有 System.exit(0); 这样的语句存在时 finally 块就不会被执行到了,因为程序被结束了。此外当在 try 块或者 catch 块里 return 时 finally 会被执行;而且 finally 块里 return 语句会把 try 块或者 catch 块里的 return 语句效果给覆盖掉且吞掉了异常。
若你觉得我的文章对你有帮助,请添加我为好友
扫描二维码,分享此文章