异常:指在程序运行过程中发生的异常事件,比如除0溢出、数组越界、文件找不到等,这些事件的发生将阻止程序的正常运行。
(这里需要注意,异常字面上的意思就是异于平常的错误,这里要和程序本身的设计错误区别开。笔者开始的时候一直在想如果一开始就知道程序会发生错误为啥还要执行它,不应该重新设计程序么?)
异常发生后,Java会通过面向对象的方法来处理异常,也就是要把错误包装成对象(这些对象都是可抛出的,即throw)。然后系统会在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理方法,这一过程称为捕获(catch)一个异常。
现在我们来看系统会抛出哪些异常:
在Java中,异常都继承自java.lang.Throwable类,它有两个直接子类:Error和Exception
1.Error类对象(如动态连接错误、硬件层面错误、JVM错误或内存不足等),由JVM生成并抛出。通常,Java程序不对这类异常进行处理,一般应用程序都无力回天。
2.Exception类对象,也就是我们通常看到的使用try、catch处理的错误,所以通常称错误处理为异常处理(Exception handling)。它又分为运行时异常(Runtime Exception),代表运行时由Java虚拟机生成的异常,如算术运算异常ArithmeticException、数组越界异常ArrayIndexOutOfBoundsEXception等;其他则为非运行时异常,如输入输出异常IOException等。 Java编译器要求Java程序必须捕获或声明所有的非运行时异常,但对运行时异常可以不做处理。
发生异常之后,处理方式有以下几种:
对运行时异常可以不做处理;使用try-catch-finally语句捕获异常;通过throws子句声明异常,还可以定义自己的异常类,并用throw语句来抛出它。
1.运行时的异常:程序在运行时检测到,它可能在程序的任意部位发生,而且其数目可能很大,此时系统会把生成的异常对象交给默认的异常处理程序,在标准输出上显示异常的内容以及发生异常的位置。
2.捕获异常,即try-catch-finally:
try{
Java statements
}catch(ExceptionType1 ExceptionObject){
Exception Handling
}catch(ExceptionType2 ExceptionObject){
Exception Handling
}.....
}finally{
final Handling
}
try后用大括号{}指定一段代码,表示该段代码可能会抛出一个或多个异常;
catch语句的参数类似方法的声明,包括一个异常类型和一个异常对象。,catch语句可以有一个或多个,而且至少有一个catch语句或finally语句;
finally语句可指定一块代码,无论try指定的程序抛不抛出异常,也不管catch语句的异常类型是否与所抛出的异常的类型一致,finally所指定的代码都要被执行,它提供了统一的出口。
3.异常的抛出:通过throw语句来实现,格式为throw ThrowableObject;
其中ThrowableObject必须为Throwable类或其子类的对象。
也可以定义自己的异常类,并用throw语句来抛出它。关于throw的和throws的用法有很多值得去讲的,笔者也会在下一篇中详细描述。
总的看来,Java的异常处理机制把异常事件当作对象来处理,利用类的层次性可以把多个具有相同父类的异常统一处理,也可以区分不同的异常分别处理,使用灵活 。
但建议:1.异常控制的设计宗旨并不是用来代替一些简单的测试
2.不要过分细化异常,以免造成资源浪费。
3.不要关闭异常
4.对于自定义的异常类,通常把它作为Exception类的子类,而非Error类的子类。且定义类名时常以Exception结尾。
对于异常处理机制的使用值得多思考,要做到在恰当的时候使用恰当的异常处理方式,而这些都是在实践总结的基础上才能得到自己的经验啦!