Java异常的概念
2016-06-09 02:06
369 查看
异常的概念
程序运行的环境是复杂的,程序在执行过程中可能遇到各种错误。如程序打开的文件不存在、网络连接遇到中断、除零操作、操作数越界等等。方法执行中遇到意外/例外/异常的情况/条件,称为异常(事件)。意外情况可能是不恰当的外部环境,可能是方法调用者传递了不恰当的实参——即错误环境或非法参数。作为方法的设计者,通常希望方法被调用时满足其前置条件,但是,不能够因为调用者没有遵守契约——如在网络服务器未启动时发出网络连接请求,于是服务代码就导致死机、死循环或其他后果。
比较String.charAt(int index)方法。其文档为:在index索引取值范围从 0 到length()-1时,返回指定索引处的 char 值,否则,抛出索引超界异常:IndexOutOfBoundsException。而[例程 8‑1为什么需要Exception]中给出了任性的代码。
/** * @return 如果索引范围从 0 到 length() - 1,遵循String.charAt(int)的契约; * 如果不遵循契约,就没有String.charAt(int)那么好说话。 */ public static char charAt(int index ){//取 -1、2、7 if(index< 0 || index >=str.length()){ // 成员变量 str = "yqj2065"; return (char)(Math.random() * 26 + 'a'); }else { return str.charAt(index); } }服务的设计者,必须考虑到可能发生的异常事件、必须考虑抛出异常对象、做好本方法的文档使方法具有良好的接口。有义务对方法参数的有效性进行检查。不管方法的文档中是否使用前置条件对参数加以明确地说明,非法参数的检查是方法实现的第一步。对异常事件进行了防御性编程。
良好的异常设计,能够提高程序的可读性、可维护性、健壮性。Java通过面向对象的方式处理异常,最大限度地调解了程序的正确性和清晰性(可读性和可维护性)间的矛盾。
Java语言将各种各样的异常事件加以数据抽象,所有的错误或异常都抽象为一个可以被抛出的对象,即java.lang.Throwable的(各种具体子类的)对象。
遇到异常事件咋办
当程序执行遇到异常事件,程序是就此结束运行还是应该从异常事件中恢复呢?这就得看异常事件的严重程度。(1)病入膏肓就让程序安乐死—— 严重的系统错误封装为Error。
(2)大病小灾还得救死扶伤,
(3)程序bug引起的(不应该出现的异常事件)则不予理会(打电话给编写那段导致异常代码的程序员,让他修改)。需要剔除的异常封装为RuntimeException。
Error和RuntimeException是程序不需要加以处理的,需要在源代码中寻找逻辑或用法错误并修改。Exception及Exception的非RuntimeException子类,编译器认为方法的调用者必须处理这类异常,也会监督、检查调用者是否处理了该异常,故称它们为被检查的异常(checked Exceptions),一般称为检查型异常,口语化为“要处理的异常”。
Error:程序员不抛出、不捕捉、不处理。
RuntimeException:由系统通过默认的异常处理程序自动抛出,自行处理。不强制要求程序员捕捉和处理。调试程序时改正。
检查型异常:方法头中用throws子句声明,方法体中以throw语句抛出;调用者以throws子句向上推卸处理责任、或者使用try-catch捕捉和处理。
抛出异常
Java程序(你的类、以及JDK类库或第三方包中的代码)和Java虚拟机都可能抛出异常。JVM自动抛出的异常,如StackOverflowError等Error、遇到4/0抛出ArithmeticException。我们关注的是,在方法体中手工抛出异常。手工抛出异常,指方法在执行过程中遭遇某种异常事件,从而创建相应的Throwable对象并抛出。例如:
throw new IndexOutOfBoundsException();
你不要抛出非Throwable对象,如throw new Dog(),程序将无法通过编译。抛出的应该是检查型异常。
一旦执行了throw语句,JVM新建一个异常对象、终止本方法的执行流程,返回到方法的调用者希望得到处理。
如果该异常是检查型异常,调用者(1)准备了catch子句进行异常处理;(2)官僚主义地使用throws子句,将异常处理推到调用者的调用者。
如果该异常是非检查异常,调用者又没有附加的异常处理代码,系统将调用默认的异常处理流程,在标准输出设备上打印/输出该异常对象的堆栈使用轨迹。
方法头的throws子句,说明本方法将抛出的若干异常。throws子句主要用于两种场合:
各种Java书籍在讲解IO流、网络编程时,为了集中精力,书中的例程常常使用throws以保持代码的简短。在实际编程中,官僚主义地throws是不好的风格。许多程序员经常忘记处理异常,或者将异常处理推迟到遥远的未来。
方法体中使用throw语句抛出的所有检查型异常,必须在方法头中throws该异常(或者其父类)。换言之,throws子句严格地强制性要求程序员:方法体中只能够使用throw语句抛出throws子句中声明的检查型异常类型或子类型。
相关文章推荐
- java单例设计模式
- 开源组件:(4)用元数据和BeanUtils写一个简单的ORM映射BaseDAO.java
- win7下eclipse配置maven
- java枚举
- java期中作业
- Ubuntu 安装JDK
- SpringMVC-整合Spring整合
- SpringMVC-interceptor
- java泛型
- win7下安装eclipse(java EE版)
- java中的实例方法、类方法和构造方法
- Dom4j解析XML文件,处理来至XML的数据信息
- Mybatis实现数据CURD操作实例
- Netbeans8.1 IDE编辑技巧(三)
- Dom4j错误:java.lang.NoClassDefFoundError: org/jaxen/JaxenException
- win7下安装jdk
- JAVA--Iterator
- Java concurrent包介绍及使用
- mysql-connector-java 6.02 错误
- Leet Code 26 删除有序数组中重复元素 - Java