异常类
异常分为受检异常(checked exception)和非受检异常(unchecked exception),也称为编译时异常(unruntime exception)和运行时异常(runtime exception)。
受检异常/编译时异常:在编译时被强制检查的异常称为"受检查的异常", 即在方法的声明中声明的异常。对可容错处理的情况使用受检异常。
非受检异常/运行时异常:在方法的声明中没有声明,但在方法的运行过程中发生的各种异常被称为"不被检查的异常"。这种异常是错误,会被自动捕获。对编程错误使用运行时异常。
![](https://img.haomeiwen.com/i16357841/6e8917f3ff4c0193.jpg)
异常处理
在程序运行发生异常时,捕获异常并处理或抛弃异常,使程序继续正常运行。
try-catch-finally:try语句块不能单独使用,必须和catch或finally子句配合使用。当有多个catch子句时,最多只会执行其中一个catch语句块中的异常处理代码,若处理的多个异常之间存在继承关系,则应先处理其子类异常,即处理子类异常的catch子句要放在前面,否则编译不通过。
参考:https://www.cnblogs.com/cjeandailynotes/p/10565597.html
结论:
1、不管有没有出现异常,finally块中代码都会执行。
2、当try和catch中有return时,finally仍然会执行。finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的。
3、finally中最好不要包含return,否则程序会提前退出,导致最终的返回值不是try或catch中保存的返回值。举例:
情况1:try{} catch(){} finally{} return;
显然程序按顺序执行。情况2:try{ return; } catch(){} finally{} return;
程序先执行try块中return之前的代码(包括return语句中的表达式运算);
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前的代码(包括return语句中的表达式运算),再执行finally语句中全部代码,
最后执行catch块中return,finally之后的代码不再执行。
无异常:执行完try再finally再return.情况4:try{ return; } catch(){} finally{return;}
程序执行try块中return之前的代码(包括return语句中的表达式运算);
再执行finally块,因为finally块中有return所以提前退出。情况5:try{} catch(){return;} finally{return;}
程序执行catch块中return之前的代码(包括return语句中的表达式运算);
再执行finally块,因为finally块中有return所以提前退出。情况6:try{ return;} catch(){return;} finally{return;}
程序执行try块中return之前的代码(包括return语句中的表达式运算);
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。最终结论:任何执行try或者catch中的return语句之前,如果finally存在的话,都会先执行finally语句。如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的。
编译器把finally中的return实现为一个warning。// 测试程序 public class FinallyTest { public static void main(String[] args) { System.out.println(new FinallyTest().test()); } static int test() { int x = 1; try { x++; return x; } finally { ++x; } } }
运行结果是2。
在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。
自定义异常
自定义异常来处理特殊的情况。
自定义异常类一般都以Exception类为父类。
自定义异常类对象只能用throw语句抛出。
敏感异常列表
异常名称 | 信息泄露/威胁描述 |
---|---|
java.io.FileNotFoundException | 泄露文件系统结构和文件名列举 |
java.util.jar.JarException | 泄露文件系统结构 |
java.util.MissingResourceException | 资源列举 |
java.security.acl.NotOwnerException | 所有人列举 |
java.util.ConcurrentModificationException | 可能提供线下不安全的代码信息 |
javax.naming.InsufficientResourcesException | 服务器资源不足(可能有利于DoS攻击) |
java.net.BindException | 当不信任客户端能够选择服务器端口时造成开放端口列举 |
java.lang.OutOfMemoryError | DoS |
java.lang.StackOverflowError | DoS |
java.sql.SQLException | 数据库结构,用户名列举 |
运行时异常列表
异常名称 | 描述 |
---|---|
java.lang.ArithmeticException | 算数异常 |
java.lang.ArrayIndexOutOfBoundsException | 数组下标越界异常 |
java.lang.ClassCastException | 类转换异常 |
java.lang.ClassNotFoundException | 指定的类不存在异常 |
java.io.IOException | 输入输出异常 |
java.lang.IllegalArgumentException | 方法参数异常 |
java.lang.IllegalAccessException | 无访问权限异常 |
java.lang.IndexOutOfBoundsException | 下标越界异常 |
java.lang.NullPointerException | 空指针异常 |
java.lang.NoSuchMethodError | 方法不存在异常 |
java.lang.NumberFormatException | 数字格式异常 |
java.sql.SQLException | sql语句执行异常 |
网友评论