异常主要包括下面三种类型
"检查性异常"描述了正确程序中所发生的问题,这些问题一般情况下是因为外在环境的条件不满足而引起的,如用户错误及I/O问题.例如,程序试图打开一个并不存在的远程Socket端口.这种错误不能归结到程序本身逻辑的错误,而很有可能是远程机器名字 错误(用户拼写错误)引起的.如果这个远程机器名是用户输入提供的,这种错误不可避免,对于一个商业型的软件系统,程序的开发者必须处理这个问题并恢复系统.Java编译器强制要求你处理这类异常,如果没有捕捉这类异常,程序将不能被编译.
"运行期异常"通常意味着程序存在Bug,如数组越界,被0除,入参不满足规范等这类问题导致运行期的异常.这类异常一般需要通过更改程序来避免.所以Java编译器比强制要求开发人员处理这类异常.
"错误"一般情况下是非常少见的,也很难通过程序来解决它.它可能源于一个程序Bug,但一般情况下更可能来源于环境的问题,如内存耗尽等问题."错误"在程序中无须处理它,而又运行环境处理.
在使用finally时,在以下特殊情况,finally块不会被执行:
在finally块中发生了异常
程序所在的线程死亡.
在前面的代码中用System.exit()退出运行.
关闭CPU.
对于多个异常的捕捉处理
处理规则:子类异常的处理块必须在父类异常的处理块之前,否则会发生编译错误.如
try
{
}
catch(GrandchildException e1)
{
...
}
catch(ChildException e2)
{
.....
}
catch(ParentExceotion e3)
{
....
}
巧妙利用异常
当方法体中的代码发生异常时,可以不予处理直接将异常"踢"给调用者.此外,也可通过语句产生一个异常.
自己编写的的程序也可以向外抛出异常,首先实例化一个异常对象,然后用throw关键字将这个异常抛出去.合在一起如throw new IOException("文件不存在");
将这两步合起来的好处是:在创建异常时会包含其创建处的行信息,异常被捕捉时可以通过Stack Trace的形式报告这些信息.如果在同一行代码创建和抛出异常,对于程序的调试将非常有用.