Java JDBC 实现反思

2006-08-03 19:08

 

在 Java 中,因为 JDBC 很多函数都抛出 SQLException,程序员用 JDBC 不得不写很多 try catch finally 之类的代码,这一点已经是众所周知的问题。众多的 O/R mapping 或者 JDBC 封装工具类,在吹自己的好处的时候,都不忘了和 JDBC 比较一把,“用我就不用写这么多乱七八糟的 try catch”。问题在于,既然 JDBC 设计的有这么多人觉得不好,为什么没有人去建议 Sun 公司改进一吧?这是一个非常让人迷惑的事情。

 

这里面暴露了 Java 中两个问题: Exception 语法问题、interface 语法问题。

Exception 应不应该用,在 C++ 时代就有很多争论,在目前的大多数比较有名气的开源项目中,要么,只用 C 不用 C++,要么用 C++ 但不用 Exception,用 C++ Exception 的很少。这里面的原因在于,在 C++ 中 throw Exception,会破坏结构化程序设计的一个最基本原则:一个函数只有一个入口,一个出口。在其他语言中,一个函数有多个出口也许没有什么问题,最多只是代码的可读性、维护性不好,在 C++ 中,一个致命的问题,资源释放问题,强烈要求,函数只能有一个出口。

比如如下代码:


funA(){
  A *a = new A();
  funT(a);
  delete a;
}
		

这样的代码,如果一开始,funT 中没有 throw Exception,这样的代码没有自然释放问题;如果某一天,有人将 funT 中增加这么一段代码:


funT(A *a){
  ....
  if(xx){
    throw exception;
  }
  ....
}
		

则以上函数 funA 中,就存在内存泄漏问题:如果funT 运行到 throw exception,funA 中 delete 根本就不会执行到。如果 funA 归程序员 jack 负责, funT 归 tom 负责,jack 只看 funA 也许永远也不会意识到 funA 有内存泄漏问题。

在 Java 中,虽然不存在内存泄漏问题,但是存在资源释放关闭问题,比如关闭文件之类的。像 Spring、Hibernate 之类的工具包,将 SQLException 封装成 RuntimeException ,同样让人迷惑。

比如以下 Java 伪代码:


open file;
read file;
dao.saveFileData();  // throw exception inside
close file;
		

如果 saveFileData 抛异常的话, close file 根本执行不到。按照目前流行的方法, DAO 函数抛异常都是 RuntimeException,编译器不会提醒你去 try catch,这里面出错的可能性大大提高。

目前已经有人在呼吁,Java coding 中也不要用 exception。

另一个问题是 Java 中 interface 语法问题。

Java 中 interface 语法非常糟糕,JDK 任何一个 interface 一旦发布后,做任何修改(增加函数、修改函数、去掉函数),都会导致已有的程序员代码,使用新的 JDK 编译不能通过问题。

比如,JDK 中有一个 interface 叫 Serializable, 这是一个空的 interface(非常莫名其妙的设计),假定某天 Sun 决定给这个 interface 需要增加 readObject,writeObject , 这就有问题了。很多已经写了这样的代码:


public class M implements Serializable{
  ....
}
		

如果新的 JDK 中,Serializable 多了两个函数,用新的 JDK 去编译已有的代码 class M,就会编译不通过。这实际上将 Sun 放在一个非常尴尬的处境:你可以在新的 JDK 中往 class 中增加函数,比如 Sun 可以在 JDK 1.3 省级到 1.4 的时候,往 String 类中增加一个函数 replaceAll,但是 Sun 不能改动任何 interface。不能升级 JDK 中的 interface 意味着,Sun 在 JDK 1.0 中发布的 interface ,在 JDK 1.4 中要原封不动,在以后的版本中也要永远不动。这个要求太高了!!!

为什么 Sun 写不出一个象 ADO 一样的 JDBC,不用抛 Exception 的 JDBC 规范出来?

 

 

欢迎转载,转载请注明出处: https://www.zheguisoft.com/staff_blogs/jacklondon_chen/2006, 及 https://blog.csdn.net/jacklondon/article/details/1015608?spm=1001.2014.3001.5501