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

創(chuàng)新互聯(lián)建站是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、微信小程序定制開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10余年以來,已經(jīng)為上1000+成都水電改造各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)。現(xiàn)在,服務(wù)的上1000+客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。
對于大部分人來說,第一次見到 class.forName(String className) 這句代碼應(yīng)該是在使用 JDBC 方式連接數(shù)據(jù)庫的時候。
實例
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ù)庫是 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.
大概翻譯一下就是:返回一個給定類或者接口的一個 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。
本文名稱:詳解Javaclass.forname功能
標(biāo)題路徑:http://www.5511xx.com/article/ccoihoi.html


咨詢
建站咨詢
