很多时候,我们在使用jdbc连接数据库时,常常会用到下面的代码:

    Class.forName("com.mysql.jdbc.Driver");   
    String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";   
    String user = "";   
    String psw = "";   
    Connection con = DriverManager.getConnection(url,user,psw);  

那Class.forName究竟有什么用呢?
当使用一个类的时候(比如new一个类的实例),jvm会检查此类是否被加载到内存,如果没有,则会执行加载操作,加载操作的内容是,读取类对应的class文件数据,解析此数据,构造一个此类对应的Class类的实例,此Class类的实例描述了类的结构,并且提供了调用此类成员的接口。此时jvm就可以使用该类了,比如实例化此类,或者调用此类的静态方法。
Java也提供了手动加载类的接口,class.forName()方法就是其中之一。初始化参数指定的类,并且返回此类对应的Class实例。
假设一个类以前从来没有被装进内存过,Class.forName(String className)这个方法会做以下几件事情:
1、装载。将字节码读入内存,并产生一个与之对应的java.lang.Class类对象
2、连接。这一步会验证字节码,为static变量分配内存,并赋默认值(0或null),并可选的解析符号引用(这里不理解没关系)
3、初始化。为类的static变量赋初始值,假如有static int a = 1;这个将a赋值为1的操作就是这个时候做的。除此之外,还要调用类的static块。

MySQL官网有这么一段话:

When you are using JDBC outside of an application server, the DriverManager class manages the establishment of connections.
Specify to the DriverManager which JDBC drivers to try to make Connections with. The easiest way to do this is to use Class.forName() on the class that implements the java.sql.Driver interface. With MySQL Connector/J, the name of this class is com.mysql.jdbc.Driver. With this method, you could use an external configuration file to supply the driver class name and driver parameters to use when connecting to a database.

翻译如下:
DriverManager管理着与数据库连接的建立,同时JDBC驱动需要跟DriverManager建立连接,最简单的方法就是对com.mysql.jdbc.Driver(java.sql.Driver接口的实现)使用Class.forName()

我们来看看JDBC驱动部分源码:

    package com.mysql.jdbc   
      
    public class Driver extends NonRegisteringDriver implements java.sql.Driver {   
     // ~ Static fields/initializers   
     // --------------------------------------------- //   
     // Register ourselves with the DriverManager   
     //   
     static {   
        t ry {   
                  java.sql.DriverManager.registerDriver(new Driver());   
              } catch (SQLException E) {   
                  throw new RuntimeException("Can't register driver!");   
              }   
      }   
    // ~ Constructors   
     // -----------------------------------------------------------   
    /**  
      * Construct a new driver and register it with DriverManager  
      *   
      * @throws SQLException  
      *             if a database error occurs.  
      */  
     public Driver() throws SQLException {   
         // Required for Class.forName().newInstance()   
     }   
    }  

从上面可以看出,在我们在使用Class.forName()加载数据库驱动时,会自动执行static块里面的代码,向DriverManager注册,这时调用DriverManager的getConnection方法,相应的Driver类已经被加载到jvm中,并且完成了类的初始化工作了,就可以愉快的操作数据库了。

当然,我们也是可以使用

com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();

这个过程同样会执行静态块里面的注册,只是我们并没有必要创建实例。
但是不能使用下面的代码,因为下面的代码之后加载类到jvm,并不会初始化,也就是说不会执行static块里面的代码

ClassLoader cl = new ClassLoader();   
cl.loadClass("com.mysql.jdbc.Driver");

发表评论

电子邮件地址不会被公开。 必填项已用*标注