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.
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。