日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

理解class.forName()(good--字节码层面)

發布時間:2025/7/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 理解class.forName()(good--字节码层面) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用jdbc方式連接數據庫時會使用一句代碼Class.forName(String?className).這句話是什么意思呢?首先說一點Class.forName(String?className)這個方法的作用是裝載className這個字符串指定的類。

官方文檔

返回與帶有給定字符串名的類或接口相關聯的?Class?對象。調用此方法等效于:

??Class.forName(className,?true,?currentLoader)

?其中?currentLoader?表示此類的定義類加載器。

例如,以下代碼片段返回?java.lang.Thread?類的運行時?Class?描述符。

???Class?t?=?Class.forName("java.lang.Thread")

?調用?forName("X")?將導致名為?X?的類被初始化。

參數:

className?-?所需類的完全限定名。

返回:

具有指定名的類的?Class?對象。

通俗的說就是:獲得字符串參數中指定的類,并初始化該類

類裝載

類裝載就是把一個類或是一個接口的字節碼文件,通過解析該字節碼來構建代表這個類或是這個接口的實例的過程。?
這個字節碼文件來源可能是壓縮包、網絡、運行時編譯出的或者自動生成的class文件,jvm?spec沒有規定必須從什么地方加載。

類裝載的兩種方式:

1.Class?c1?=?Class.forName?("java.lang.String");?

2.ClassLoader?cl?=?new??ClassLoader();?

Class?cl.loadClass(?String?name,?boolean?resolve?);

?

兩種裝載方法的區別:

不同的類裝載器

??Class.forName是從指定的classloader中裝載類,如果沒有指定,也就是一個參數的時候,是從裝載當前對象實例所在的classloader中裝載類。

??而ClassLoader的實例調用loadclass方法,是指從當前ClassLoader實例中調用類,而這個實例與裝載當前所在類實例的Classloader也許不是同一個.?

??????說白了就是他們實現裝載的時候,使用的類裝載器的指定是不同的。那為什么使用不同的ClassLoader來裝載類呢?

??? ??其實使用多個classloader加載類的情況非常常見,比如說我們的app?server都是這樣的.?在Web與EJB間,?他們的classLoader就是不同的,這樣做的目的就是為了避免兩者間類裝載的相互干擾。

是否實例化類

??????Class的裝載分了三個階段,loading(裝載),linking(連接)和initializing(實例化)分別定義在The?Java?Language?Specification的12.2,12.3和12.4。

?Class.forName(className)實際上是調用Class.forName(className,?true,?this.getClass().getClassLoader())。注意第二個參數,是指Class被loading后是不是必須被初始化

? ??ClassLoader.loadClass(className)實際上調用的是ClassLoader.loadClass(name,?false),第二個參數指出Class是否被link

? ??區別就出來了。Class.forName(className)裝載的class已經被實例化,而ClassLoader.loadClass(className)裝載的class還沒有被link,所以就更談不上實例化了。

??一般情況下,這兩個方法效果一樣,都能裝載Class。但如果程序需要Class被實例化,就必須用Class.forName(name)了。

例如,在JDBC中加載mysql的驅動類時(關于注冊jdbc驅動請參看另外一篇文章,jdbc注冊驅動的三種方式),Class.forName("com.mysql.jdbc.Driver"),
如果換成getClass().getClassLoader().loadClass("com.mysql.jdbc.Driver"),就不行,因為它只是向jvm裝載了Driver并沒有實例化,就不能執行響應的操作。

?打開com.mysql.jdbc.Driver的源代碼看看,

// Register ourselves with the DriverManager static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException E) {throw new RuntimeException("Can't register driver!");} }

可以看到,Driver在static塊中會注冊自己到java.sql.DriverManager。而static塊就是在Class的初始化中被執行。所以這個地方就只能用Class.forName(className)。

?

資源

http://blog.csdn.net/yanwushu/article/details/7574713

1.http://www.iteye.com/topic/15039?

2.Class.forName和ClassLoader.loadClass的比較

http://blog.csdn.net/lu7kang/article/details/5576043?

3.自定義ClassLoader?

http://software.ccidnet.com/pub/disp/Article?columnID=294&articleID=25857&pageNO=1?

?4.ClassLoader分析?

http://blog.csdn.net/longdick/article/details/1873795?

轉載于:https://www.cnblogs.com/softidea/p/4000137.html

總結

以上是生活随笔為你收集整理的理解class.forName()(good--字节码层面)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。