聊聊Java中的异常及处理( 二 )


  • try
一个try语句必须带有至少一个catch语句块或一个finally语句块。当异常处理的代码执行结束以后,不会再回到try语句去执行尚未执行的代码 。
  • catch
每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象 。在此介绍一些常用的方法,这些方法均继承自Throwable类。
  1. toString ()方法,显示异常的类名和产生异常的原因 。
  2. getMessage()方法,只显示产生异常的原因,但不显示类名 。
  3. printStackTrace()方法,用来跟踪异常事件发生时堆栈的内容 。
这里有一个需要特别注意的地方,那就是catch捕获异常时的捕获顺序:
如果异常类之间有继承关系,在顺序安排上就需注意 。越是顶层的类,越放在下面,再不然就直接把多余的catch省略掉 。也就是说先捕获子类异常再捕获父类异常 。
  • finally
finally语句块中始终都要执行,除了遇到了System.exit(0)结束程序运行 。针对这个特性,所以我们通常在finally中关闭程序块已打开的资源,比如:关闭文件流、释放数据库连接等 。
即使try和catch块中存在return语句,finally语句也会执行 。是在执行完finally语句后再通过return退出 。
在这里就有一道非常经典的一个面试题 。
public class Test {public static void main(String[]args) {System.out.println(new Test().test());;}static int test(){int x = 1;try{retun x;}finally{System.out.print("jdbk"+ ++x);}}}// 问输出结果?先解释哈这里存在的玄妙吧!
看了上面的讲述,我们都知道了当try和catch中有return时,finally仍然会执行,所以正常逻辑来说此题的答案应该是“jdbk2 2”,但这里存在一个陷阱,那就是:
finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保 存起来,不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是 在finally执行前确定的 。因此正确答案应该是:“jdbk2 1” 。
还有一点需要注意的就是:finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值 。
接下来再来讲讲声明异常吧,它相对来说就比较简单了 。
在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理 。如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开 。
public static void readFile(String fileName) throws FileNotFoundException,IOException {}需要注意的地方就是:
  1. 在方法重写中声明异常时:子类重写父类方法时,如果父类方法有声明异常,那么子类声明的异常范围不能超过父类声明的范围 。
  2. 声明异常我们一般在server层中 。在controller层或则数据访问层一般是捕获异常 。
自定义异常我们为什么要自定义异常?还不是因为在程序中,可能会遇到JDK提供的任何标准异常类都无法充分描述清楚我们想要表达的问题 。此时我们就可以创建自己的异常类,即自定义异常类 。
那我们怎么自定义异常类呢?相信你看了上面的异常类的家族图应该就猜到了 。不错,自定义异常类只需从Exception类或者它的子类派生一个子类即可 。如果你继承Exception类,则为受检查异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常RuntimeException类 。通常我们自定义异常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器 。这里举一个例子 。
/**IllegalAgeException:非法年龄异常,继承Exception类*/class IllegalAgeException extends Exception {//默认构造器public IllegalAgeException() {}//带有详细信息的构造器,信息存储在message中public IllegalAgeException(String message) {super(message);}}public void setAge(int age) throws IllegalAgeException {if (age < 0) {throw new IllegalAgeException("人的年龄不应该为负数");}this.age = age;}最后给大家讲述一点使用异常机制的建议:
1.要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下 。
2.处理异常不可以代替简单测试---只在异常情况下使用异常机制 。
3.不要进行小粒度的异常处理---应该将整个任务包装在一个try语句块中 。
4.异常往往在高层处理 。

【聊聊Java中的异常及处理】


推荐阅读