浅析使用浅析使用JDBC操作操作MySQL需要添加需要添加
Class.forName("com.mysql.jdbc.Driver")
主要介绍了使用JDBC操作MySQL需要添加Class.forName("com.mysql.jdbc.Driver")的相关知识,非常不错,具
有一定的参考借鉴价值 ,需要的朋友可以参考下
引言引言
如果熟悉使用JDBC来连接数据库的同学一定很清楚连接数据库的代码中一定会有依据Class.forName
("com.mysql.jdbc.Driver");
public static Connection getConnection() throws ClassNotFoundException, SQLException {
if(connection == null){
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxx?serverTimezone=UTC", "root", "xxxxxx");
}
return connection;
}
之前没有想过为什么需要有这么一个语句,都是按照文档直接这么做的,在这篇文章中我来试着解释这么做的原因。
类加载机制类加载机制
在这之前我们先来说下Java中的类加载机制。
在Java中如果想要使用一个类,则必须要求该类已经被加载到Jvm中,加载的过程实际上就是通过类的全限定名来获取定义该
类二进制字节流,然后将这个字节流所表示的静态存储结构转换为方法去的动态运行时数据结构。同时在在内存中实例化一个
java.lang.Class对象,作为方法区中该类的数据访问入口(供我们使用)。
而会触发类加载的会有如下几种情况(引用自<<深入理解Java虚拟机>>):
1.遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成
这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已
在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3.当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
Class.forName
在Java官方文档中对Class.forName的解释为在运行时动态的加载一个类,返回值为生成的Class对象。
那么很明显在jdbc中使用Class.forName("com.mysql.jdbc.Driver");仅仅就是将com.mysql.jdbc.Driver类加载到Jvm中了,这个原因大
多数人应该都知道。
但是我们要知道Class.forName貌似只是对类进行了加载,我们甚至都没有对返回的Class对象做任何操作,那么我们为什么
后面就可以直接用了呢?
首先看Class.forName调用了native方法forName0(...);
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
private static native Class<?> forName0(String name, boolean initialize,ClassLoader loader,Class<?> caller);
要注意forName0中有一个关键的参数boolean initialize,;该参数用来标识在将该类加载后是否进行初始化操作。可以看到代码
中是true,就表示会进行初始化操作。
初始化过程实际上就是对变量赋值(不是赋初值,不会调用构造函数)的过程。包含所有类变量的赋值以及静态代码语句块的执
行代码,包括对父类的初始化。
再看com.mysql.jdbc.Driver驱动类:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
评论0