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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

深入研究Java类加载机制

發(fā)布時間:2025/6/15 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入研究Java类加载机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
深入研究Java類加載機制 ? 類加載是Java程序運行的第一步,研究類的加載有助于了解JVM執(zhí)行過程,并指導(dǎo)開發(fā)者采取更有效的措施配合程序執(zhí)行。 研究類加載機制的第二個目的是讓程序能動態(tài)的控制類加載,比如熱部署等,提高程序的靈活性和適應(yīng)性。 ? 一、簡單過程 ? Java程序運行的場所是內(nèi)存,當在命令行下執(zhí)行: java HelloWorld 命令的時候,JVM會將HelloWorld.class加載到內(nèi)存中,并形成一個Class的對象HelloWorld.class。 其中的過程就是類加載過程: 1、尋找jre目錄,尋找jvm.dll,并初始化JVM; 2、產(chǎn)生一個Bootstrap Loader(啟動類加載器); 3、Bootstrap Loader自動加載Extended Loader(標準擴展類加載器),并將其父Loader設(shè)為Bootstrap Loader。 4、Bootstrap Loader自動加載AppClass Loader(系統(tǒng)類加載器),并將其父Loader設(shè)為Extended Loader。 5、最后由AppClass Loader加載HelloWorld類。 ? 以上就是類加載的最一般的過程。 ? 二、類加載器各自搜索的目錄 ? 為了弄清楚這個問題,首先還要看看System類的API doc文檔。 ? ?
相關(guān)值的描述
java.versionJava 運行時環(huán)境版本
java.vendorJava 運行時環(huán)境供應(yīng)商
java.vendor.urlJava 供應(yīng)商的 URL
java.homeJava 安裝目錄
java.vm.specification.versionJava 虛擬機規(guī)范版本
java.vm.specification.vendorJava 虛擬機規(guī)范供應(yīng)商
java.vm.specification.nameJava 虛擬機規(guī)范名稱
java.vm.versionJava 虛擬機實現(xiàn)版本
java.vm.vendorJava 虛擬機實現(xiàn)供應(yīng)商
java.vm.nameJava 虛擬機實現(xiàn)名稱
java.specification.versionJava 運行時環(huán)境規(guī)范版本
java.specification.vendorJava 運行時環(huán)境規(guī)范供應(yīng)商
java.specification.nameJava 運行時環(huán)境規(guī)范名稱
java.class.versionJava 類格式版本號
java.class.pathJava 類路徑
java.library.path加載庫時搜索的路徑列表
java.io.tmpdir默認的臨時文件路徑
java.compiler要使用的 JIT 編譯器的名稱
java.ext.dirs一個或多個擴展目錄的路徑
os.name操作系統(tǒng)的名稱
os.arch操作系統(tǒng)的架構(gòu)
os.version操作系統(tǒng)的版本
file.separator文件分隔符(在 UNIX 系統(tǒng)中是“/”)
path.separator路徑分隔符(在 UNIX 系統(tǒng)中是“:”)
line.separator行分隔符(在 UNIX 系統(tǒng)中是“/n”)
user.name用戶的賬戶名稱
user.home用戶的主目錄
user.dir用戶的當前工作目錄
? 可惜這個幫助文檔并不全,直接用程序打印出來如下: ????????????????for?(Map.Entry<Object, Object> entry : System.getProperties().entrySet()) {?
????????????????????????System.out.println(entry.getKey()+"\t"+entry.getValue());?
????????????????}
?
java.runtime.nameJava(TM) SE Runtime Environment
sun.boot.library.pathQ:\jdk6\jre\bin
java.vm.version14.0-b16
java.vm.vendorSun Microsystems Inc.
java.vendor.urlhttp://java.sun.com/
path.separator;
idea.launcher.port7532
java.vm.nameJava HotSpot(TM) Client VM
file.encoding.pkgsun.io
sun.java.launcherSUN_STANDARD
user.countryCN
sun.os.patch.levelService Pack 3
java.vm.specification.nameJava Virtual Machine Specification
user.dirE:\projects\testScanner
java.runtime.version1.6.0_14-b08
java.awt.graphicsenvsun.awt.Win32GraphicsEnvironment
java.endorsed.dirsQ:\jdk6\jre\lib\endorsed
os.archx86
java.io.tmpdirC:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\
line.separator
java.vm.specification.vendorSun Microsystems Inc.
user.variant
os.nameWindows XP
sun.jnu.encodingGBK
java.library.pathQ:\jdk6\bin;.;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;Q:\jdk6\bin;Q:\JavaFX\javafx-sdk1.2\bin;Q:\JavaFX\javafx-sdk1.2\emulator\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\MySQL Server 5.1\bin;C:\Program Files\StormII\Codec;C:\Program Files\StormII
java.specification.nameJava Platform API Specification
java.class.version50
sun.management.compilerHotSpot Client Compiler
os.version5.1
user.homed:\我的文檔
user.timezone
java.awt.printerjobsun.awt.windows.WPrinterJob
idea.launcher.bin.pathC:\IDEA8\bin
file.encodingUTF-8
java.specification.version1.6
java.class.pathQ:\jdk6\jre\lib\alt-rt.jar;Q:\jdk6\jre\lib\charsets.jar;Q:\jdk6\jre\lib\deploy.jar;Q:\jdk6\jre\lib\javaws.jar;Q:\jdk6\jre\lib\jce.jar;Q:\jdk6\jre\lib\jsse.jar;Q:\jdk6\jre\lib\management-agent.jar;Q:\jdk6\jre\lib\plugin.jar;Q:\jdk6\jre\lib\resources.jar;Q:\jdk6\jre\lib\rt.jar;Q:\jdk6\jre\lib\ext\dnsns.jar;Q:\jdk6\jre\lib\ext\localedata.jar;Q:\jdk6\jre\lib\ext\sunjce_provider.jar;Q:\jdk6\jre\lib\ext\sunmscapi.jar;Q:\jdk6\jre\lib\ext\sunpkcs11.jar;E:\projects\testScanner\out\production\testScanner;C:\IDEA8\lib\idea_rt.jar
user.nameAdministrator
java.vm.specification.version1
java.homeQ:\jdk6\jre
sun.arch.data.model32
user.languagezh
java.specification.vendorSun Microsystems Inc.
awt.toolkitsun.awt.windows.WToolkit
java.vm.infomixed mode, sharing
java.version1.6.0_14
java.ext.dirsQ:\jdk6\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
sun.boot.class.pathQ:\jdk6\jre\lib\resources.jar;Q:\jdk6\jre\lib\rt.jar;Q:\jdk6\jre\lib\sunrsasign.jar;Q:\jdk6\jre\lib\jsse.jar;Q:\jdk6\jre\lib\jce.jar;Q:\jdk6\jre\lib\charsets.jar;Q:\jdk6\jre\classes
java.vendorSun Microsystems Inc.
file.separator\
java.vendor.url.bughttp://java.sun.com/cgi-bin/bugreport.cgi
sun.io.unicode.encodingUnicodeLittle
sun.cpu.endianlittle
sun.desktopwindows
sun.cpu.isalist
? 1、Bootstrap Loader(啟動類加載器):加載System.getProperty("sun.boot.class.path")所指定的路徑或jar。
2、Extended Loader(標準擴展類加載器ExtClassLoader):加載System.getProperty("java.ext.dirs")所指定的路徑或jar。在使用Java運行程序時,也可以指定其搜索路徑,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld ? 3、AppClass Loader(系統(tǒng)類加載器AppClassLoader):加載System.getProperty("java.class.path")所指定的路徑或jar。在使用Java運行程序時,也可以加上-cp來覆蓋原有的Classpath設(shè)置,例如: java -cp ./lavasoft/classes HelloWorld ? ExtClassLoader和AppClassLoader在JVM啟動后,會在JVM中保存一份,并且在程序運行中無法改變其搜索路徑。如果想在運行時從其他搜索路徑加載類,就要產(chǎn)生新的類加載器。 ? 三、類加載器的特點 ? 1、運行一個程序時,總是由AppClass Loader(系統(tǒng)類加載器)開始加載指定的類。 2、在加載類時,每個類加載器會將加載任務(wù)上交給其父,如果其父找不到,再由自己去加載。
3、Bootstrap Loader(啟動類加載器)是最頂級的類加載器了,其父加載器為null.
? 四、類加載器的獲取 ? 很容易,看下面例子 public?class?HelloWorld {?
????????public?static?void?main(String[] args) {?
????????????????HelloWorld hello =?new?HelloWorld();?
????????????????Class c = hello.getClass();?
????????????????ClassLoader loader = c.getClassLoader();?
????????????????System.out.println(loader);?
????????????????System.out.println(loader.getParent());?
????????????????System.out.println(loader.getParent().getParent());?
????????}?
}
? 打印結(jié)果: sun.misc.Launcher$AppClassLoader@19821f?
sun.misc.Launcher$ExtClassLoader@addbf1?
null?

Process finished with exit code 0
? 從上面的結(jié)果可以看出,并沒有獲取到ExtClassLoader的父Loader,原因是Bootstrap Loader(啟動類加載器)是用C語言實現(xiàn)的,找不到一個確定的返回父Loader的方式,于是就返回null。 ? 五、類的加載 ? 類加載有三種方式: 1、命令行啟動應(yīng)用時候由JVM初始化加載 2、通過Class.forName()方法動態(tài)加載 3、通過ClassLoader.loadClass()方法動態(tài)加載 ? 三種方式區(qū)別比較大,看個例子就明白了: public?class?HelloWorld {?
????????public?static?void?main(String[] args)?throws?ClassNotFoundException {?
????????????????ClassLoader loader = HelloWorld.class.getClassLoader();?
????????????????System.out.println(loader);?
????????????????//使用ClassLoader.loadClass()來加載類,不會執(zhí)行初始化塊?
????????????????loader.loadClass("Test2");?
????????????????//使用Class.forName()來加載類,默認會執(zhí)行初始化塊?
//????????????????Class.forName("Test2");?
????????????????//使用Class.forName()來加載類,并指定ClassLoader,初始化時不執(zhí)行靜態(tài)塊?
//????????????????Class.forName("Test2", false, loader);?
????????}?
}
? public?class?Test2 {?
????????static?{?
????????????????System.out.println("靜態(tài)初始化塊執(zhí)行了!");?
????????}?
}
? 分別切換加載方式,會有不同的輸出結(jié)果。 ? 六、自定義ClassLoader ? 為了說明問題,先看例子: package?test;?

import?java.net.MalformedURLException;?
import?java.net.URL;?
import?java.net.URLClassLoader;?

/**?
* 自定義ClassLoader?
*?
* @author leizhimin 2009-7-29 22:05:48?
*/?
public?class?MyClassLoader {?
????????public?static?void?main(String[] args)?throws?MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException {?
????????????????URL url =?new?URL("file:/E:\\projects\\testScanner\\out\\production\\testScanner");?
????????????????ClassLoader myloader =?new?URLClassLoader(new?URL[]{url});?
????????????????Class c = myloader.loadClass("test.Test3");?
????????????????System.out.println("----------");?
????????????????Test3 t3 = (Test3) c.newInstance();?
????????}?
}
? public?class?Test3 {?
????????static?{?
????????????????System.out.println("Test3的靜態(tài)初始化塊執(zhí)行了!");?
????????}?
}
? 運行后: ----------?
Test3的靜態(tài)初始化塊執(zhí)行了!?

Process finished with exit code 0
? 可以看出自定義了ClassLoader myloader = new URLClassLoader(new URL[]{url});已經(jīng)成功將類Test3加載到內(nèi)存了,并通過默認構(gòu)造方法構(gòu)造了對象Test3 t3 = (Test3) c.newInstance(); ? 有關(guān)ClassLoader還有很重要一點: 同一個ClassLoader加載的類文件,只有一個Class實例。但是,如果同一個類文件被不同的ClassLoader載入,則會有兩份不同的ClassLoader實例(前提是著兩個類加載器不能用相同的父類加載器)。

總結(jié)

以上是生活随笔為你收集整理的深入研究Java类加载机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。