原创

【每天十分钟JAVA快速入门】(十二)异常

异常

首先要意识到这个世界上没有不会发生错误的程序,任何程序都有可能在某种情况下出现bug或发生异常,无论你编写代码的水平有多高,即使你的代码天衣无缝,依然避免不了发生错误,比如网络无法连接,访问的文件不存在等等这些我们无法掌控的环境问题。Java使用异常捕获机制来处理程序运行中出现的异常情况,以便于我们在异常发生时采取必要的措施,如通知用户、记录错误日志、保存相关数据、释放占用的资源等等。

分类
Java中的所有异常类都是继承与Throwable类,Throwable下分为Error和Exception。Error是系统内部错误,如编译错误,运行时系统资源耗尽等,我们在编写代码时不应该抛出Error,而是需要关注Exception。
Exception又派生为RuntimeException和其他异常,RuntimeException的名字似乎有些太大,事实上其他异常大多数都是发生在“运行时”。
RuntimeException的典型代表是空指针异常,数组越界异常,类型转换异常等等,一般来说出现RuntimeException说明我们代码写得有问题,不够健壮,我们应该杜绝这类异常的发生。
其他异常例如IOException,出现这类异常的原因是由环境决定而不是由程序决定,例如访问一个不存在的文件,出现这类异常不代表我们的代码有缺陷,我们也无法杜绝这样的异常发生。

声明
我们在定义一个方法时应当声明(使用throws关键字)所有可能抛出的异常,上面提到了RuntimeException我们是需要杜绝的,Error我们无法掌控,因此这里声明的异常应该是除了RuntimeException和Error之外的异常,这样的异常我们统称为检查异常,例如:
public boolean createNewFile() throws IOException{
...
}

子类如果覆盖了父类的方法,父类方法没有抛出异常,子类方法也不能抛出的异常。如果父类方法有抛出异常,子类方法不能比父类方法抛出的异常更通用。

抛出
在程序设计过程中,如果事先预计到会发生一些异常情况,我们需要决定抛出什么类型的异常,在异常发生时使用throw关键字抛出相应类型的的异常,例如我们编写一个解析文件的方法,接收的文件有一定的格式要求,如果不满足我们就抛出文件格式异常。
首先可以自定义一个文件格式异常,自定义异常必须要继承某个异常类
public class FileFormatException extends IOException{
public FileFormatException() {}
public FileFormatException(String msg) {
super(msg)
}
...
}
现在我们在自己的方法里就可以抛出这个自定义异常了:
String readFile(String path) throws FileFormatException{
if(invalidFormat){
throw new FileFormatException();
}
}

捕获
上面我们已经在方法中抛出了异常,如果该异常没有得到任何处理,程序将会终止,这显然不是我们想要的。那我们该怎么办呢,就像打篮球一样,你抛出球总归需要有队友去接,否则不是出界就是被对方抢断了,这都不是我们想要的结果。事实上方法中抛出的异常如何处理应该是方法的调用者关心的问题,Java中使用try/catch语句块来捕获并处理异常,例如:
try{
readFile("sample.txt")
}catch (FileFormatException e){
...
}

finally
当我们程序中的方法发生异常时,就不会再运行方法剩余的代码,并退出该方法,如果该方法获取了一些系统资源,而且只有它自己才知道,则会出现资源回收的问题。因此我们需要有一种机制在发生异常时还能够做什么额外的处理工作,finally语句就提供了这样的功能。
不管是否有异常被捕获,finally里的代码都会执行,这就是它的作用,例如:
try{
readFile("sample.txt")
}catch (FileFormatException e){
...
}finally{
release resources...
}



正文到此结束