java编程思想阅读笔记(六)异常处理

本文探讨了Java中异常机制的初衷、抛出与捕获、限制以及具体实现细节,通过实例展示了如何在代码中合理使用异常处理,增强程序的健壮性和可维护性。重点介绍了异常链的概念,以及如何通过异常栈轨迹追踪问题源头。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“Java的基本理念是:结构不佳的代码不能运行。”,从我原来使用Java的异常机制的感觉是不太喜欢的,因为他将整个异常的调用轨迹都放出来了,给人一种恐怖的感觉,现在慢慢体会着这里面的种种好处,感受着他们的设计思路。
1.开发异常的初衷
在Java中,异常机制的使用的初衷是为了方便程序员处理可能的错误,其中一个重要原则是“只有在你知道如何处理的情况下才捕获异常”,同时也是将错误处理代码与正常运行逻辑的代码分开,增强可阅读与可维护性。如果常使用c语言的话,常常函数的调用是通过返回值来进行可能存在错误的判断,一旦情况复杂,直接干扰了正常运行逻辑的理解,看到的全是对可能问题的处理,因此,往往很少充分的去处理(这样确实简单,可以通过调试跟踪来解决,这个可能就是对问题的处理方式不同吧)。书中阐述了些“被检查的异常”和强静态类型检查对开发健壮程序的看法,强调异常报告和类型检查的重要性,但是也不限制死;自己在C语言中深感其灵活性(也是经常被弄得混乱无助),但在Java中还没有特别切身的感受,不好多说,留下来。
2.异常的抛出与捕获
(1)异常的产生
java.lang.Throwable是 Java 语言中所有错误或异常的基类。其直接子类为Error和Exception,Error用来表示系统的错误,一般应用程序不需要关心;Exception需要应用程序关心,是类库、用户方法及运行时可抛出的基本类型。只有当对象是Throwable(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。因此通常情况下,可以通过catch Exception来捕获想要的(关心的)所有异常,如果没有处理好同时也带来“吞食”异常的问题。
(2)抛出与捕获(异常栈轨迹)
可以通过继承Exception或者更为细的异常类型来创建自己所需要的异常,然后使用throw来抛出异常,遵循Java的对象使用,异常对象也是通过new在堆上创建,而且可以通过无参数的和带字符串为参数的构造器来构造异常对象,例如中的throw new NullPointerException("t = null");或者还能够通过cause来构造异常链。
异常的捕获是将可能产生异常的语句放在try块中,然后在catch中处理异常;要说的是,可以通过printStackTrace()方法显示异常的调用栈轨迹,可以在捕获处来显示异常的调用轨迹,但是这里也涉及到如果未处理好异常,异常重新抛出后,栈轨迹的变化问题:如果想保留原来的调用栈轨迹,就直接抛出异常;而如果想更新这个信息,可以调用fillInStackTrace()方法。
异常链,保存的所有异常的信息。Throwable的子类(Error、Exception、RuntimeException)在构造器中可以接受一个cause对象作为参数,这个cause可以作为新异常产生的前因,从而记录所有异常信息。
(3)finally
使用finally清理,无论try块中的异常是否抛出,它们都能得到执行,即使finally所连接的try方法中有return语句,也会保证finally的执行;虽然不能用作清理内存析构函数之类,但是可以在打开的文件或网络连接等地方使用。
3.异常的限制
当覆盖方法时,只能抛出在基类方法的异常说明里列出的异常,从而使得基类使用的代码(方法)能够用到其子类上;当然,这个限制对构造器是不起作用的,但是子类的构造器的异常说明必须包含基类的异常说明,而且子类的构造器是不能捕获基类构造器抛出的异常。

最后一个异常的使用例子:通过printStackTrace()来进行异常栈轨迹的查看,而通过getCause()获取产生此异常发生的直接原因(异常),因而得到整个异常链。

package com.test.myjava; /* * @author w7849516230 */ class FirstException extends Exception{ /* * 利用默认的构造器 * Exception(String message, Throwable cause) 构造带指定详细消息和原因的新异常 * 下同 */ FirstException(String str,Exception e){ super(str,e); } } class SecondException extends Exception{ public SecondException(String str, Exception e) { super(str,e); } } class ThirdException extends Exception{ public ThirdException(String str) { super(str); } } public class ExceptionTest { public void firstMethod() throws FirstException{ try { secondMethod(); } catch (SecondException e) { throw new FirstException("FirstException Test",e); } } public void secondMethod() throws SecondException{ try { thirdMethod(); } catch (ThirdException e) { throw new SecondException("SecondException Test",e); } } public void thirdMethod() throws ThirdException{ throw new ThirdException("ThirdException Test"); } public static void main(String[] args){ ExceptionTest et = new ExceptionTest() ; //打印异常栈 try { et.firstMethod(); } catch (FirstException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { et.firstMethod(); } catch (Exception e) { try { throw e.getCause();//捕获特定的异常进行处理 }catch(FirstException ef){ System.out.println("Catch FirstException!"); }catch(SecondException es){ System.out.println("Catch SecondException!"); try { throw es.getCause(); }catch(ThirdException eth){ System.out.println("In SecondException Catch ThirdException!"); }catch (Throwable e1) { // TODO Auto-generated catch block System.out.println("Catch Exception in SecondException"); e1.printStackTrace(); } }catch(ThirdException eth){ System.out.println("Catch ThirdException"); } catch (Throwable e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } }

输出:

com.test.myjava.FirstException: FirstException Test at com.test.myjava.ExceptionTest.firstMethod(ExceptionTest.java:34) at com.test.myjava.ExceptionTest.main(ExceptionTest.java:53) Caused by: com.test.myjava.SecondException: SecondException Test at com.test.myjava.ExceptionTest.secondMethod(ExceptionTest.java:41) at com.test.myjava.ExceptionTest.firstMethod(ExceptionTest.java:32) ... 1 more Caused by: com.test.myjava.ThirdException: ThirdException Test at com.test.myjava.ExceptionTest.thirdMethod(ExceptionTest.java:45) at com.test.myjava.ExceptionTest.secondMethod(ExceptionTest.java:39) ... 2 more Catch SecondException! In SecondException Catch ThirdException!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值