java中Class.forName方法的作用详解
前言
在做JAVAEE开发的过程中,更多的是使用框架来提高开发效率.越来越发现,之前很基础的一些东西,都忘记的差不多了.从今天开始慢慢的复习一下基础.今天在看JDBC的时候,就有一个有趣的地方,之前学的时候,也没在意.这个Class.forName究竟是什么鬼.
连接数据库几大步.看以下代码
importcom.mysql.jdbc.Driver;
importjava.sql.*;
/**
*@authorhonway.liu
*@date2016/12/8下午11:07
*@emailgm100861@gmail.com
*@bloghttp://linuxsogood.org
*/
publicclassJdbcDemo{
publicstaticvoidmain(String[]args)throwsSQLException,ClassNotFoundException{
Stringurl="jdbc:mysql://127.0.0.1:3306/mydb";
Stringusername="root";
Stringpassword="redhat";
Class.forName("com.mysql.jdbc.Driver");
Connectionconnection=DriverManager.getConnection(url,username,password);
Stringsql="SELECT*FROMmsg";
PreparedStatementprepareStatement=connection.prepareStatement(sql);
ResultSetresultSet=prepareStatement.executeQuery();
resultSet.next();
Stringaddress=resultSet.getString("address");
System.out.println(address);
}
}
其中第一步,搞的我有点想不通.为啥Class.forName传入了一段字符串之后,就知道我连接的数据库是mysql?有点不科学啊.Class.forName到底做了啥.下面就开始到源码中,一探究竟.
@CallerSensitive
publicstaticClass>forName(StringclassName)
throwsClassNotFoundException{
Class>caller=Reflection.getCallerClass();
returnforName0(className,true,ClassLoader.getClassLoader(caller),caller);
}
发现它调用了forName0方法,继续跟踪再看看
privatestaticnativeClass>forName0(Stringname,booleaninitialize, ClassLoaderloader, Class>caller) throwsClassNotFoundException;
native方法,源码也只能到此结束了.看下官方文档,怎么说吧.
https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String)
发现官方文档,还是描述的很清楚的.
ReturnstheClassobjectassociatedwiththeclassorinterfacewiththegivenstringname, usingthegivenclassloader. Giventhefullyqualifiednameforaclassorinterface(inthesameformatreturnedbygetName) thismethodattemptstolocate,load,andlinktheclassorinterface. Thespecifiedclassloaderisusedtoloadtheclassorinterface. Iftheparameterloaderisnull,theclassisloadedthroughthebootstrapclassloader. Theclassisinitializedonlyiftheinitializeparameteristrueandifithasnotbeen initializedearlier.
嗯,描述的还算是很清楚.返回一个给定类或者接口的一个Class对象,如果没有给定classloader,那么会使用根类加载器.如果initalize这个参数传了true,那么给定的类如果之前没有被初始化过,那么会被初始化.我们在JDBC第一步的时候,传入的参数是com.mysql.jdbc.Driver.也就是说这个类会被初始化.我们看一下这个类里面的内容.
publicclassDriverextendsNonRegisteringDriverimplementsjava.sql.Driver{
static{
try{
java.sql.DriverManager.registerDriver(newDriver());
}catch(SQLExceptionE){
thrownewRuntimeException("Can'tregisterdriver!");
}
}
publicDriver()throwsSQLException{
//RequiredforClass.forName().newInstance()
}
}
我们发现这个类也是超级简单的.一个构造函数和一个静态代码块.我们知道,类在初始化的时候,静态代码块的内容会被执行的.也就是说我们Class.forName和直接写DriverManager.registerDriver(newDriver)两者功能是等同的.我们换成这种写法.再试试看.
publicclassJdbcDemo{
publicstaticvoidmain(String[]args)throwsSQLException,ClassNotFoundException{
Stringurl="jdbc:mysql://127.0.0.1:3306/mydb";
Stringusername="root";
Stringpassword="redhat";
//Class.forName("com.mysql.jdbc.Driver");
DriverManager.registerDriver(newDriver());
Connectionconnection=DriverManager.getConnection(url,username,password);
Stringsql="SELECT*FROMmsg";
PreparedStatementprepareStatement=connection.prepareStatement(sql);
ResultSetresultSet=prepareStatement.executeQuery();
resultSet.next();
Stringaddress=resultSet.getString("address");
System.out.println(address);
}
}
发现代码,还是正常的执行了.
总结一下:
Class.forName方法的作用,就是初始化给定的类.而我们给定的MySQL的Driver类中,它在静态代码块中通过JDBC的DriverManager注册了一下驱动.我们也可以直接使用JDBC的驱动管理器注册mysql驱动.从而代替使用Class.forName.
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。