时间:2021-07-01 10:21:17 帮助过:2人阅读
Class.forName(String className)方法会将这三步都做掉,如下面的例子:
package com.ticmy.oracle;
public class TestClinit {
public static void main(String[] args) throws Exception {
Class.forName( "com.ticmy.oracle.ABC" );
}
}
class ABC {
private static int a = getNum();
static {
System.out.println( "this is static block" );
}
public static int getNum() {
System.out.println( "getNum" );
return 1 ;
}
}
|
程序的运行结果是:
getNum
this is static block
那么,Class.forName(driver)这个driver类里有没有什么static块呢?去探究一下。例子用的是Oracle,反编译下oracle.jdbc.OracleDriver,发现其继承了oracle.jdbc.driver.OracleDriver,那么继续看这个oracle.jdbc.driver.OracleDriver,确实有个static块,里面有这样的代码:
static {
Timestamp localTimestamp = Timestamp.valueOf( "2000-01-01 00:00:00.0" );
try {
if (defaultDriver == null ) {
defaultDriver = new OracleDriver();
DriverManager.registerDriver(defaultDriver);
}
} catch (RuntimeException localRuntimeException) {
} catch (SQLException localSQLException){}
_Copyright_2004_Oracle_All_Rights_Reserved_ = null ;
}
|
再看看mysql吧:com.mysql.jdbc.Driver:
同样发现了static块,里面代码如下:
static {
try {
DriverManager.registerDriver( new Driver());
} catch (SQLException E) {
throw new RuntimeException( "Can‘t register driver!" );
}
}
|
再看一个db2:com.ibm.db2.jcc.DB2Driver:
也发现了static块:
static {
if (o.Nb != null ) {
exceptionsOnLoadDriver__ = dg.a(o.Nb, exceptionsOnLoadDriver__);
}
try {
registeredDriver__ = new DB2Driver();
DriverManager.registerDriver(registeredDriver__);
}
catch (SQLException localSQLException) {
exceptionsOnLoadDriver__ = new SqlException( null ,
"Error occurred while trying to register Jcc driver with JDBC 1 Driver Manager" );
exceptionsOnLoadDriver__.setNextException(localSQLException);
}
}
|
无一例外地,发现里面都有DriverManager.registerDriver(driver)的调用。那么是不是可以将开头的例子中的Class.forName换成DriverManager.registerDriver呢?
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl" ;
String user = "scott" ;
String password = "ticmy" ;
DriverManager.registerDriver( new OracleDriver());
Connection conn = DriverManager.getConnection(url, user, password);
System.out.println(conn);
conn.close();
|
经过测试发现OK。现在,已经知道Class.forName(driver)的根本目的就是为了调用DriverManager.registerDriver。
Class.forName还有个重载的方法:Class.forName(String name, boolean initialize, ClassLoader loader),Class.forName(String className)就等价于Class.forName(className, true, currentLoader),注意中间的参数为true,这个参数的含义就是要不要初始化。如果此参数为true且指定的类以前没有被初始化过,就会去初始化。
另外,jdbc4已经不需要显式的调用Class.forName了,在jdbc4中,调用getConnection的时候DriverManager会自动去加载合适的驱动。
http://www.ticmy.com/?p=249
JDBC在getConnection之前为什么要调用Class.forName(转)
标签: