JDBC在getConnection之前为什么要调用Class.forName

转载 2016年08月28日 23:54:03

获取一个数据库连接的通用模板如下:

String driver = "oracle.jdbc.OracleDriver";

String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";

String user = "scott";

String password = "ticmy";

Class.forName(driver);

Connection conn = DriverManager.getConnection(url, user, password);

里面有个Class.forName(driver),这句话有什么作用?将驱动类load到内存?如果没有这句会怎么样?运行发现,如果去掉这一句会有以下异常:
java.sql.SQLException: No suitable driver found for xxx….

在解释具体原因之前先简单看下Class.forName做了什么。

假设一个类以前从来没有被装进内存过,Class.forName(String className)这个方法会做以下几件事情:
1、装载。将字节码读入内存,并产生一个与之对应的java.lang.Class类对象
2、连接。这一步会验证字节码,为static变量分配内存,并赋默认值(0或null),并可选的解析符号引用(这里不理解没关系)
3、初始化。为类的static变量赋初始值,假如有static int a = 1;这个将a赋值为1的操作就是这个时候做的。除此之外,还要调用类的static块。(这一步是要点)

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(Stringname, boolean initialize, ClassLoader loader),Class.forName(StringclassName)就等价于Class.forName(className, true, currentLoader),注意中间的参数为true,这个参数的含义就是要不要初始化。如果此参数为true且指定的类以前没有被初始化过,就会去初始化。

另外,jdbc4已经不需要显式的调用Class.forName了,在jdbc4中,调用getConnection的时候DriverManager会自动去加载合适的驱动。

jdbc加载驱动 Class.forName()的作用

在学习jdbc时,我们首先学到的是最简单的helloWorld入门,但是为什么要这样呢 ? //注册驱动 Class.forName("com.mysql.jd...
  • u010644448
  • u010644448
  • 2016年07月12日 23:05
  • 3197

Class.forName()的作用与使用总结

目录(?)[+] 1、Class类简介:  Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方...
  • Zhangxichao100
  • Zhangxichao100
  • 2016年04月16日 15:57
  • 4826

写一个直接获取JDBC到数据库连接的工具包(一)

其实就是新建一个类,类中实现一定的功能 首先需要建立一个配置文件,即键值对,注意:配置文件要放在src下,建立一个jdbconfig.properties文件,并添加键值对 JdbcUti...
  • fandoudou123
  • fandoudou123
  • 2016年01月07日 21:26
  • 1151

Class.forName("com.mysql.jdbc.Driver");的作用

使用JDBC时,我们都会很自然得使用下列语句: java 代码 Class.forName("com.mysql.jdbc.Driver");    String url = "jd...
  • memray
  • memray
  • 2012年03月02日 11:48
  • 4867

JDBC Class.forName引发的思考

jdbc连接的代码一般都是这样:package com.xiangyi.test; import java.sql.Connection; import java.sql.DriverManage...
  • fengwind1
  • fengwind1
  • 2016年07月21日 11:43
  • 253

关于Class.forName(“com.mysql.jdbc.Driver”)

传统的使用jdbc来访问数据库的流程为: Class.forName(“com.mysql.jdbc.Driver”); String url = “jdbc:mysql://localhost:...
  • x356982611
  • x356982611
  • 2016年07月14日 00:41
  • 588

JDBC中Class.forName()的作用

使用JDBC时Class.forName()的作用Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装...
  • github_27609763
  • github_27609763
  • 2015年05月27日 15:48
  • 1623

使用JDBC时Class.forName()的作用

使用JDBC时,我们都会很自然得使用下列语句: Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql...
  • wud_jiyanhui
  • wud_jiyanhui
  • 2011年09月22日 15:44
  • 338

JDBC连结中Class.forName()详解

java开发中,采用JDBC连接数据库,最经常用到的就是Class.forName()这个方法. Class.forName(String className)在JDK帮助文档中是这样说的:返回与带有...
  • renhui999
  • renhui999
  • 2013年07月24日 09:28
  • 1008

JDBC Class.forName(); 原代码讲解

使用JDBC时,我们都会很自然得使用下列语句: Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://12...
  • jlhnxly
  • jlhnxly
  • 2011年08月29日 19:32
  • 941
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JDBC在getConnection之前为什么要调用Class.forName
举报原因:
原因补充:

(最多只允许输入30个字)