Error handling
错误处理是指 编程、应用程序和通信中错误的预测、检测和解决。
“Abnormals” in Java
所有异常对象的基类都是java.lang。可抛出的,以及它的两个子类java.lang。异常和java.lang.Error
Error and Exception
-Error类描 述Java虚拟机内部错误(资源耗尽和系统错误等),多数情况下无需处 理,也无法处理
-Exception类描述程序 导致的错误,需要处理
Exceptions
·异常处 理机制将允许代码将错误或者异常事件传递给调用它的代码。
·当方法不能正常完成时,提供 了另外一个退出路径
·方法抛出异常,停止执行,不返回任何值,不执行后续代码
·异常处 理机制捕获异常,寻找到可以处理此异常的代码进行处理。
**Classification of exceptions**
Exceptions are derived from Throwable
在Java编程语言中,异常对象总是派生自Throwable的类的实例
RuntimeException and Other Exceptions
the exception hierarchy in Java异常的层次结构
unchecked exceptions(Error + RuntimeException)
Programming error, other unrecoverable failure(不可恢复故障)
不要求必须捕获处理
Checked exception
要 求必须捕获处理,compiler会进行检查
Common Unchecked Exception Classes
1.ArrayIndexOutOfBoundsException
当您的代码使用数组索引(超出数组边界)时,由JVM抛出
2.NullPointerException
当代码试图在需要对象引用的地方使用null引用时,JVM抛出
3.NumberFormatException
当试图将字符串转换为数字类型,但是字符串没有适当的格式时,通过编程抛出(例如,由Integer.parseInt())
4.ClassCastException
当试图转换对象引用失败时,JVM抛出
5.IllegalArgumentException
以编程方式抛出示方法被传递了一个非法或不合适的参数。您可以对自己的方法重用此异常
6.IllegalStateException
当方法被调用且程序不处于该方法执行其任务的适当状态时,以编程方式抛出种情况通常发生在方法被不按顺序调用时,或者一个方法只允许被调用一次,并且尝试再次调用它时
7.NoClassDefFoundError
在找不到类定义时由JVM或类加载器抛出
Checked Exception Handling Operations
Five keywords are used in exception handling: try, catch, finally, throws and throw
Java’s exception handling consists of three operations
– 声明异常(throws)
– 抛出异常 (throw)
– 捕获异常 (try, catch, finally)
Declaring Checked Exceptions by throws
方法不仅可以告诉编 译器返回值是什么,也可以声明会出现什么样的错误
例如,试图从文件中读取的代码知道该文件可能不存在或为空。因此,试图处理文件中的信息的代码将需要通知编译器它可以抛出某种IOException
声明方法可以抛出异常的位置是方法的头部;头更改以反映方法可以抛出的已检查异常
会抛出 异常的四种情况 :
- 调用的方法抛出了异常
- 自己的方法抛出了异常
- 程序存在错误
- 虚拟机 或者运行时类库错误
不需要为方法声明出所有可能的异常,但是前两种情况需要声明
Declare more than one Checked Exceptions
如果一个方法可能抛出多个已检查的异常类型,则必须在头文件中列出所有异常类。用逗号分隔它们,如下面的示例所示
Don’t throw Error and unchecked exceptions
不需要声明Error类型的异常
不需要声明RuntimeException 类型的异常
小结:
一个 方法必须声明它可能抛出的所有checked异常。
Compiler会检查是否所有checked异 常都被正确声明了
Unchecked异常不需要处理(要么无法处理,要么不 应该发生)
How to Throw an Exception
假设您有一个方法readData,它正在读取文件。您的代码中发生了一些可怕的事情。▪你可能认为这种情况非常不正常,所以你想抛出一个 EOFException异常(当输入过程中意外到达文件或流的末尾时),说明“在输入过程中意外到达EOF的信号”。
EOFException有第二个构造函数,它接受一个字符串参数。
▪你可以通过更仔细地描述异常情况来很好地利用这一点
如果现有的异常类中有一个对您有效,则很容易抛出异常
1.找到或者设计合适的异常类
2.创建异常类的对象
3.抛出
一旦方法抛出一个异常,它就不会返回 到调用者,这意味着不需要担心会产生默认返回值或错误编码。
Creating Exception Classes
您的代码可能会遇到任何标准异常类都无法充分描述的问题。
▪在这种情况下,很容易创建自己的异常类。
▪只要从Exception派生它,或者从一个子类(如IOException)派生它
习惯上同时给出一个默认构造函数 和一个包含详细消息的构造函数。
Catching Exceptions
如果异常发生在任何地方都没有捕获到,程序将终止并向控制台打印一条消息,给出异常的类型和堆栈跟踪。
▪GUI(图形用户界面Graphical User Interface)程序捕获异常,打印堆栈跟踪消息,然后返回到用户界面处理循环。
▪为了捕获异常,设置一个try/catch块
当try块中出现异常时,将忽略出现异常位置之后的代码,由catch子句进行异 常处理
- 无异常时,catch子句不执行
- 如果 catch语句中没有匹配的异常处理,则被访问的程序退出。
Pass the exception on to the caller
另一种处理异常的策略:将异 常处理交给调用者,某些情况下,调用者更清楚如何处理。
此时,需要在方法声明中声明异常
- 调用声明了checked异常的方法,则必须处理异常或继续传
Try/catch and throw an exception?
准则:处理知道如何处理的异常,传播不知道如何处理的异常
传播异常时,通过 throws通知调用者处理
注意:
- 如果子类方法重写了父类方法,父类方法没有抛出异常,则 子类方法中需要catch所有的checked异常(不能继续传播)
- 子类继承自父类的方法,在子类 中不能增加异常
finally Clause
问题:出现异常时,需要清理 已经占用的资源
Java 有更好的处理方法: the finally clause
Try-Catch-Finally
Finally部分的代码,是否捕获异常都会被执行
Case 1: 没有抛出异常
在本例中,程序首先执行try块中的所有代码。-然后,执行finally子句中的代码。-然后,在finally子句之后执行第一个语句。-换句话说,执行通过点1、2、5和6。
Case 2: 抛出一个 被捕获的异常,catch没有继续抛出异常
程序执行try块中的所有代码,直到抛出异常为止。try块中的其余代码将被跳过。然后,程序执行匹配catch子句中的代码,然后执行finally子句中的代码。-如果catch子句没有抛出异常,程序执行finally子句后面的第一行。-执行通过点1、3、4、5和6。
Case 3: 抛出一个被捕获 的异常,catch继续抛出异常
程序执行try块中的所有代码,直到抛出异常为止。try块中的其余代码将被跳过。然后,程序执行匹配catch子句中的代码,然后执行finally子句中的代码。如果catch子句抛出异常,则该异常将被返回给该方法的调用者,并且执行仅通过点1、3和5。
Case4: 抛出一个未被捕获的异常
在这里,程序执行try块中的所有代码,直到抛出异常。-跳过try块中的剩余代码。-然后,执行finally子句中的代码,并将异常返回给该方法的调用者
Using finally without a Catch
可以使用finally子句而不使用catch子句
不管try块中是否遇到异常,都会执行finally子句中的in.close()语句。
▪如果遇到异常,它将被重新抛出,并且必须在另一个catch子句中捕获