java中Class.forName方法的作用詳解
前言
在做JAVA EE開發(fā)的過程中,更多的是使用框架來提高開發(fā)效率.越來越發(fā)現(xiàn),之前很基礎(chǔ)的一些東西,都忘記的差不多了.從今天開始慢慢的復(fù)習(xí)一下基礎(chǔ).今天在看JDBC的時候,就有一個有趣的地方,之前學(xué)的時候,也沒在意.這個Class.forName
究竟是什么鬼.
連接數(shù)據(jù)庫幾大步.看以下代碼
import com.mysql.jdbc.Driver; import java.sql.*; /** * @author honway.liu * @date 2016/12/8 下午11:07 * @email gm100861@gmail.com * @blog http://linuxsogood.org */ public class JdbcDemo { public static void main(String[] args) throws SQLException, ClassNotFoundException { String url = "jdbc:mysql://127.0.0.1:3306/mydb"; String username = "root"; String password = "redhat"; Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection(url, username, password); String sql = "SELECT * FROM msg"; PreparedStatement prepareStatement = connection.prepareStatement(sql); ResultSet resultSet = prepareStatement.executeQuery(); resultSet.next(); String address = resultSet.getString("address"); System.out.println(address); } }
其中第一步,搞的我有點想不通.為啥Class.forName
傳入了一段字符串之后,就知道我連接的數(shù)據(jù)庫是mysql? 有點不科學(xué)啊.Class.forName
到底做了啥.下面就開始到源碼中,一探究竟.
@CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }
發(fā)現(xiàn)它調(diào)用了forName0
方法,繼續(xù)跟蹤再看看
private static native Class<?> forName0(String name, boolean initialize, ClassLoader loader, Class<?> caller) throws ClassNotFoundException;
native
方法,源碼也只能到此結(jié)束了.看下官方文檔,怎么說吧.
https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String)
發(fā)現(xiàn)官方文檔,還是描述的很清楚的.
Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.
嗯,描述的還算是很清楚.返回一個給定類或者接口的一個Class
對象,如果沒有給定classloader
,那么會使用根類加載器.如果initalize
這個參數(shù)傳了true
,那么給定的類如果之前沒有被初始化過,那么會被初始化.我們在JDBC第一步的時候,傳入的參數(shù)是com.mysql.jdbc.Driver
. 也就是說這個類會被初始化.我們看一下這個類里面的內(nèi)容.
public class Driver extends NonRegisteringDriver implements java.sql.Driver { static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } public Driver() throws SQLException { // Required for Class.forName().newInstance() } }
我們發(fā)現(xiàn)這個類也是超級簡單的.一個構(gòu)造函數(shù)和一個靜態(tài)代碼塊.我們知道,類在初始化的時候,靜態(tài)代碼塊的內(nèi)容會被執(zhí)行的.也就是說我們Class.forName
和直接寫DriverManager.registerDriver(new Driver)
兩者功能是等同的.我們換成這種寫法.再試試看.
public class JdbcDemo { public static void main(String[] args) throws SQLException, ClassNotFoundException { String url = "jdbc:mysql://127.0.0.1:3306/mydb"; String username = "root"; String password = "redhat"; //Class.forName("com.mysql.jdbc.Driver"); DriverManager.registerDriver(new Driver()); Connection connection = DriverManager.getConnection(url, username, password); String sql = "SELECT * FROM msg"; PreparedStatement prepareStatement = connection.prepareStatement(sql); ResultSet resultSet = prepareStatement.executeQuery(); resultSet.next(); String address = resultSet.getString("address"); System.out.println(address); } }
發(fā)現(xiàn)代碼,還是正常的執(zhí)行了.
總結(jié)一下:
Class.forName
方法的作用,就是初始化給定的類.而我們給定的MySQL的Driver類中,它在靜態(tài)代碼塊中通過JDBC的DriverManager
注冊了一下驅(qū)動.我們也可以直接使用JDBC的驅(qū)動管理器注冊mysql驅(qū)動.從而代替使用Class.forName
.
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項
這篇文章主要介紹了使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12關(guān)于@Autowierd && @Resource 你真的了解嗎
這篇文章主要介紹了關(guān)于@Autowierd && @Resource的具體使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08Resty開發(fā)restful版本的Jfinal深入研究
這篇文章主要為大家介紹了Resty開發(fā)restful版本的Jfinal深入研究有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03