这篇文章转载自 : JDBC在getConnection之前为什么要调用Class.forName

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

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

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

JDBC在getConnection之前为什么要调用Class.forName相关推荐

  1. JDBC对MySQL数据库存储过程的调用

    一.MySQL数据库存储过程: 1.什么是存储过程 存储过程(英文:Stored Procedure)是在大型数据库系统中,为了完毕特定功能而编写的一组的SQL语句集.存储过程经编译存储在数据库中.用 ...

  2. jdbc mysql 存储过程查询数据_jdbc调用mysql存储过程实现代码

    1. 创建存储过程 建立一个MySQL的存储过程 add_pro 复制代码 代码如下: delimiter // drop procedure add_pro // create procedure ...

  3. 润乾集算器与帆软报表集成 (直接通过 jdbc,类 DB 存储过程方式调用)

    集算器概述 集算器作为一种大数据计算工具,不仅在润乾产品体系中能发挥它的巨大作用,在其他绝大部分数据处理.数据计算领域的项目.产品中,也都有他助力计算的身影.比如传统的报表工具,报表项目中,80% 的 ...

  4. jdbc pdf_JDBC教程– ULTIMATE指南(PDF下载)

    jdbc pdf 在本文中,我们提供了全面的JDBC教程(Java数据库连接性),这是Oracle提供的API,允许程序员处理Java应用程序中的不同数据库:它允许开发人员建立与数据库的连接,定义特定 ...

  5. JDBC教程– ULTIMATE指南(PDF下载)

    在本文中,我们提供了全面的JDBC教程(Java数据库连接性),这是Oracle提供的一种API,允许程序员处理Java应用程序中的不同数据库:它允许开发人员建立与数据库的连接,定义特定的客户端如何访 ...

  6. jena 开发之 mysql数据导入_在Jena框架下基于MySQL数据库实现本体的存取操作

    转自:http://blog.csdn.net/jtz_mpp/article/details/6224311 最近在做一个基于本体的管理系统.其中对本体的操作部分,我使用的是Jena框架:数据模型是 ...

  7. jdbc存储过程mysql_JDBC对MySQL数据库存储过程的调用

    1.什么是存储过程 存储过程(英文:Stored Procedure)是在大型数据库系统中,为了完成特定功能而编写的一组的SQL语句集.存储过程经编译存储在数据库中,用户通过指定存储过程的名字并给出参 ...

  8. mysql和jdbc的区别_JDBC详解

    一. JDBC 简介 1 什么是 JDBC •JDBC(JavaDataBaseConnectivity)java 数据库连接 • 是 JavaEE 平台下的技术规范 • 定义了在 Java 语言中连 ...

  9. Java连接数据库 JDBC

    1.JDBC是什么? JDBC,英文全称:Java DataBase Connectivity,中文全称:java数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访 ...

最新文章

  1. linux环境: shell初始化文件, for TCSH, CSH
  2. linux账号管理笔记
  3. flink 4-输出
  4. Excel生成报表之解决方案--设置单个单元格格式
  5. 使用OAuth2令牌的安全REST服务
  6. LeetCode 2094. 找出 3 位偶数
  7. c语言猜四位数游戏猜10次,C语言猜数字游戏--随机生成4个不相同的数字从小到大排序,用户开始游戏,如果用户猜对数字和数字对应的位置,界面回馈A,如果数字正确位置不正确,则回馈B...
  8. java从数组中删除元素(数组的缩容)
  9. centos 中查找文件、目录、内容
  10. 配置数据库连接池的时候。
  11. 安装mysql的一些小问题
  12. 提升网站转化率的四步优化方案
  13. linux查看python安装库_linux下怎么查看python的包
  14. c#服务器后台搭建_微信影视小程序搭建拆解:第一课,影视小程序简介,搭建影视小程序的整体流程...
  15. 啦啦外卖php版本,微信外卖源码,微信啦啦外卖plus跑腿版 v5.0.7开源版
  16. android视频壁纸源码,Android 视频壁纸
  17. oracle detele,Oracle中,一个Delete操作的流程
  18. 计算机应用工程师如何评定,个人如何申请工程师职称评定
  19. larval中redis的用法
  20. 毕业论文ppt的研究方法及过程计算机专业,计算思维原理研究与实现数据组织毕业论文4喜欢就下吧(全文完整版)...

热门文章

  1. MariaDB Galera 集群安装配置
  2. hdu4847 Wow! Such Doge! KMP
  3. 字符指针,字符数组,双引号的字符串的区别与联系
  4. cocos2dx对所有子节点设置透明度
  5. Marshal.Copy 之 startIndex 参数的含义
  6. 源码|批量执行invokeAll()多选一invokeAny()
  7. 防范SQL注入的几种方法 4
  8. 2017先知创新大会:有ZHI而来
  9. Redis安装配置和介绍
  10. PHP回调函数的几种用法