jdbc之Class.forName

   今天闲来无事,看了看刚学java时候的数据库demo程序;代码再简单不过,相信大家在熟悉不过了 ,无非就是如下(以mysql为例) :

Class.forName( "com.mysql.jdbc.Driver" );

String url =  "jdbc:mysql://127.0.0.1/test" ;

String user =  "root" ;

String psw =  "root" ;

Connection con = DriverManager.getConnection(url,user,psw); 

余下了就不写了,写的话估计大家也是味同嚼蜡;

相信刚接触到数据库的朋友也回见过这在普通不过的代码了,因为是初学,所以每个人都小心翼翼的参照教科书上的步骤依葫芦画瓢,也没有人会太关心为什么那么写;还有些人说 不要太关心底层的东西;但今天我一个疑惑在我的大脑里面产生了,那就是Class.forName到底有怎么用,或许有人会说是加载数据库驱动,对那是教科书的说法,我没有说他错,但到底是怎么加载 的呢;我非常疑惑的是class.forName并没有作为任何语句的右值,也就是并没有出现我们编程中的Student s=new Student();  s.say();等常见的形式; 疑惑出现了,就要解答,我从来不习惯于也不迷信于教科书上的讲法,更何况今天有点时间;根据之前写程序的经验class.forName的作用主要有几个方面 一 获得一个类的实例 如Student.class.newInstance  二是获得classLoader  即

Student.class.getClassLoader()  第三是 执行某一个类的静态代码块 ;由于刚才已经说了,这个语句没有作为任何语句的右值,所以 第一和第二种作用可以排除,剩下的就只有第三个可能了;但问题是加载哪一个类的静态代码块呢,一时想不明白,没办法只好试用着把class.forName注释,结果就不用说了,肯定是通不过了,那唯一的解释就是该句对后面的代码有影响,于是开始看后面的代码,看DriverManage的源代码,终于弄明白了;DriverManagerz在调用getConnection方法之前,保证相应的Driver类已经被加载到jvm中,,并且完成了类的初始化工作;而DriverManger把已经加载的Driver类放到一个集合中,这一步通过registerDriver(java.sql.Driver driver),这里Driver是一个接口,每一个数据库厂商做出了不同的实现,mysql的就是com.mysql.jdbc包下的Driver了,也就是被写烂了的Class.forName("com.mysql.jdbc.Driver")了,最后看了一下Driver的源代码 ,果然在它的静态代码里面调用了DriverManager里面的registerDriver,代码如下

package com.mysql.jdbc;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver
  implements java.sql.Driver
{
  static
  {
    try
    {
      DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
      throw new RuntimeException("Can't register driver!");
    }
  }

}

 

在回头看一下oralce的也类似

package oracle.jdbc;

import oracle.jdbc.driver.OracleDriver;

public class OracleDriver extends oracle.jdbc.driver.OracleDriver
{
}

 

 

package oracle.jdbc.driver;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import oracle.jdbc.dbaccess.DBAccess;
import oracle.jdbc.dbaccess.DBError;
import oracle.jdbc.oci.OracleOCIConnection;

public class OracleDriver
  implements Driver{

.........

 

static
  {
    m_driverAccess.put("thin-server", "oracle.jdbc.thinserver.ServerTTC7Protocol");

    m_driverAccess.put("oci-server", "oracle.jdbc.ociserver.ServerOCIDBAccess");

    m_driverAccess.put("thin", "oracle.jdbc.ttc7.TTC7Protocol");
    m_driverAccess.put("oci8", "oracle.jdbc.oci8.OCIDBAccess");
    m_driverAccess.put("oci", "oracle.jdbc.oci8.OCIDBAccess");
    m_driverAccess.put("kprb", "oracle.jdbc.kprb.KprbDBAccess");

    m_defaultConn = null;
    m_defaultDriver = null;

    Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
    try
    {
      if (m_defaultDriver == null)
      {
        m_defaultDriver = new OracleDriver();
        DriverManager.registerDriver(m_defaultDriver);
      }
    }
    catch (RuntimeException localRuntimeException)
    {
    }
    catch (SQLException localSQLException)
    {
    }
  }

 

 

 

到这里所有的疑惑都解决了!

 

最后说一下类的静态代码块在什么时候被执行

1  通常的创建实例 new Student()等等

2  第一次加载这个 类到jvm,如Class.forName,Studeng.class等

注意  ClassLoader.loadclass("xxxxx")并不会触发静态代码的执行;


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值