新聞中心
Class.forName()主要功能:Class.forName(xxx.xx.xx)返回的是一個(gè)類(lèi),Class.forName(xxx.xx.xx)的作用是要求JVM查找并加載指定的類(lèi),也就是說(shuō)JVM會(huì)執(zhí)行該類(lèi)的靜態(tài)代碼段。

創(chuàng)新互聯(lián)建站是一家專(zhuān)注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃、微信小程序定制開(kāi)發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開(kāi)發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10余年以來(lái),已經(jīng)為上1000+成都水電改造各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)。現(xiàn)在,服務(wù)的上1000+客戶與我們一路同行,見(jiàn)證我們的成長(zhǎng);未來(lái),我們一起分享成功的喜悅。
對(duì)于大部分人來(lái)說(shuō),第一次見(jiàn)到 class.forName(String className) 這句代碼應(yīng)該是在使用 JDBC 方式連接數(shù)據(jù)庫(kù)的時(shí)候。
實(shí)例
import com.mysql.jdbc.Driver;
import java.sql.*;
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 傳入 com.mysql.jdbc.Driver 之后,就知道我連接的數(shù)據(jù)庫(kù)是 mysql,這是為什么呢,看看源代碼:
@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)
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.
大概翻譯一下就是:返回一個(gè)給定類(lèi)或者接口的一個(gè) Class 對(duì)象,如果沒(méi)有給定 classloader, 那么會(huì)使用根類(lèi)加載器。如果 initalize 這個(gè)參數(shù)傳了 true,那么給定的類(lèi)如果之前沒(méi)有被初始化過(guò),那么會(huì)被初始化。我們?cè)?JDBC 第一步的時(shí)候,傳入的參數(shù)是 com.mysql.jdbc.Driver。也就是說(shuō)這個(gè)類(lèi)會(huì)被初始化,我們看一下這個(gè)類(lèi)里面的內(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è)類(lèi)也是超級(jí)簡(jiǎn)單的。一個(gè)構(gòu)造函數(shù)和一個(gè)靜態(tài)代碼塊。我們知道,類(lèi)在初始化的時(shí)候,靜態(tài)代碼塊的內(nèi)容會(huì)被執(zhí)行的。也就是說(shuō)我們 Class.forName 和直接寫(xiě) DriverManager.registerDriver(new Driver) 兩者功能是等同的。我們換成這種寫(xiě)法,再試試看:
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 方法的作用,就是初始化給定的類(lèi)。而我們給定的 MySQL 的 Driver 類(lèi)中,它在靜態(tài)代碼塊中通過(guò) JDBC 的 DriverManager 注冊(cè)了一下驅(qū)動(dòng)。我們也可以直接使用 JDBC 的驅(qū)動(dòng)管理器注冊(cè) mysql 驅(qū)動(dòng),從而代替使用 Class.forName。
分享標(biāo)題:詳解Javaclass.forname功能
網(wǎng)頁(yè)鏈接:http://fisionsoft.com.cn/article/ccoihoi.html


咨詢
建站咨詢
