Welcome 微信登录

首页 / 软件开发 / JAVA / java异常处理笔记

java异常处理笔记2011-01-25 blogjava 江苏520对于一个非常熟悉 C++ 异常处理模型的程序员来说,它几乎可以不经任何其它培训和学习,就可以完全接受和能够轻松地使用 Java 语言中的异常处理编程方法。这是因为 Java 语言中的异常处理模型几乎与 C++ 中异常处理模型有 99% 的相似度,无论是从语法规则,还是语义上来说,它们二者都几乎完全一致。

当然,如果你对 Java 语言中的异常处理模型有更多,或更深入的了解,你还是能够发现 Java 异常处理模型与 C++ 中异常处理模型还是存在不少差别的。是的,Java 语言本来就是 C++ 语言的完善改进版,所以,Java 语言中的异常处理模型也就必然会继承了 C++ 异常处理模型的风格和优点。但是,好的东西不仅仅是需要继承优点,更重要的是需要“去其糟粕,取其精华”,需要发展!!!毫无疑问,Java 语言中的异常处理模型完全达到了这一“发展”高度。它比 C++ 异常处理模型更安全,更可高,更强大和更丰富。

下面的内容中,阿愚不打算再向大家详细介绍一遍有关 Java 异常处理编程的具体语法和规则。因为这与 C++ 中的异常处理几乎完全一样,而且这些基础知识在太多太多的有关 java 编程的书籍中都有详细阐述。而阿愚认为: 这里更需要的是总结,需要的是比较,需要的是重点突出,需要的是关键之处 。所以,下面着重把 Java 语言中的异常处理模型与 C++ 异常处理模型展开比较,让我们透彻分析它到底有何发展?有何优势?与 C++ 异常处理模型到底有哪些细节上的不同?又为什么要这样做?

借鉴并引进了 SEH 异常模型中的 try-finally 语法

要说 Java 异常处理模型与 C++ 中异常处理模型的最大不同之处,那就是在 Java 异常处理模型中引入了 try-finally 语法,阿愚认为这是从微软的 SEH 借鉴而来。在前面的一些文章中,详细而深入阐述 SEH 异常处理模型的时候,我们从中获知,SEH 主要是为 C 语言而设计的,便于第三厂商开发的 Window 驱动程序有更好更高的安全保障。同时,SEH 异常处理模型中除了 try-except 来用于处理异常外,还有一个 try-finally 语法,它主要用来清除一些曾经分配的资源(由于异常出现,而导致这些资源不能够按正常的顺序被释放,还记得吗?这被称为“ UNWIND ”),try-finally 本质上有点类似于面向对象编程中的析构函数的作用,由于这项机制的存在,才导致 SEH 的强大和风光无比。

现在,Java 异常处理模型也吸收了这项设计。可我们知道,无论是 JAVA 中,还是 C++ 中,它们都有“析构函数”呀!它们完全可以利用面向的析构函数来自动释放资源呀!是的,没错!理论上是这样的。可是在实践中,我们也许会发现或经常碰到,仅仅利用析构函数来释放资源,并不是那么好使,例如,我们经常需要动态得从堆上分配的对象,这时,释放对象必须要显式地调用 delete 函数来触发该对象的析构函数的执行。如果这期间发生了异常,不仅该对象在堆中的内存不能达到被释放的结果,而且,该对象的析构函数中释放更多资源的一些代码也不能得以执行。因此这种后果非常严重,这也算 C++ 异常处理模型中一种比较大的缺陷吧!(虽然,C++ 有其它补救措施,那就是利用“智能指针”来保证一些对象的及时而有效地被释放)。另外,其实很有许多类似的例子,例如关闭一个内核句柄等操作( CloseHandle )。

在 Java 语言中,由于它由于采用了垃圾回收技术,所以它能有效避免上述所讲的类似于 C++ 语言中的由于异常出现所导致的那种资源不能得以正确释放的尴尬局面。但是,它仍然还是在它的异常处理模型中引入了 try-finally 语法,因为,无论如何,它至少会给程序员带来了极大的方便,例如如下的程序片断,就可以充分反映出 try-finally 对提高我们代码的质量和美观是多么的重要。

import java.io.*;
/** *//**
author by http://www.bt285.cn http://www.5a520.cn
*/
public class Trans
{
public static void main(String[] args)
{
try
{
BufferedReader rd=null;
Writer wr=null;
try
{
File srcFile = new File((args[0]));
File dstFile = new File((args[1]));
rd = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), args[2]));
wr = new OutputStreamWriter(new FileOutputStream(dstFile), args[3]);
while(true)
{
String sLine = rd.readLine();
if(sLine == null) break;
wr.write(sLine);
wr.write(" ");
}
}
finally
{
// 这里能保证在何种情况下,文件流的句柄都得以被正确关闭
// 该方法主要用于清理非内存性质的资源(垃圾回收机制无法
// 处理的资源,如数据库连接、 Socket 关闭、文件关闭等等)。
wr.flush();
wr.close();
rd.close();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}