亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java中Class.forName方法的作用詳解

 更新時間:2017年06月29日 11:06:41   作者:honway  
Class.forName(xxx.xx.xx) 返回的是一個類,但Class.forName方法的作用到底是什么終?下面這篇文章就來給大家詳細(xì)介紹了關(guān)于java中Class.forName方法的作用,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。

前言

在做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)文章

  • springboot中.yml文件的值無法讀取的問題及解決

    springboot中.yml文件的值無法讀取的問題及解決

    這篇文章主要介紹了springboot中.yml文件的值無法讀取的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項

    使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項

    這篇文章主要介紹了使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 關(guān)于@Autowierd && @Resource 你真的了解嗎

    關(guān)于@Autowierd && @Resource 你真的了解嗎

    這篇文章主要介紹了關(guān)于@Autowierd && @Resource的具體使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 一文帶你弄懂Maven拉包(拉取依賴包)原理

    一文帶你弄懂Maven拉包(拉取依賴包)原理

    業(yè)務(wù)需求開發(fā)的時候,我們總是會遇到拉不到依賴包的情況,此時如果不清楚 Maven 拉取依賴包的原理,那么很可能找不到問題所在,今天小編就帶大家了解下 Maven 拉包的原理,讓你在遇到問題的時候能快速解決,需要的朋友可以參考下
    2023-07-07
  • SpringBoot項目整合Redis教程詳解

    SpringBoot項目整合Redis教程詳解

    這篇文章主要介紹了SpringBoot項目整合Redis教程詳解,Redis?是完全開源的,遵守?BSD?協(xié)議,是一個高性能的?key-value?數(shù)據(jù)庫。感興趣的小伙伴可以參考閱讀本文
    2023-03-03
  • java8 計算時間差的方法示例

    java8 計算時間差的方法示例

    這篇文章主要介紹了java8 計算時間差的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 關(guān)于QueryWrapper高級使用示例

    關(guān)于QueryWrapper高級使用示例

    本文介紹了QueryWrapper的高級使用方法,包括查詢指定字段、使用MySQL函數(shù)處理字段、設(shè)置查詢限制等,通過select()可查詢指定字段并處理,last()方法實現(xiàn)limit效果,apply()可在查詢條件中使用函數(shù),這些技巧有助于提升數(shù)據(jù)庫操作的靈活性和效率
    2024-09-09
  • springboot讀取配置文件中的參數(shù)具體步驟

    springboot讀取配置文件中的參數(shù)具體步驟

    在本篇文章里小編給大家分享了關(guān)于springboot讀取配置文件中的參數(shù)的相關(guān)知識點內(nèi)容,有需要的朋友們跟著學(xué)習(xí)下。
    2019-06-06
  • Resty開發(fā)restful版本的Jfinal深入研究

    Resty開發(fā)restful版本的Jfinal深入研究

    這篇文章主要為大家介紹了Resty開發(fā)restful版本的Jfinal深入研究有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Java文件操作實例詳解

    Java文件操作實例詳解

    這篇文章主要為大家詳細(xì)介紹了Java文件操作實例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評論