先回顧一下classpath
classpath的作用:
classpath的作用是指定查找類的路徑:當使用java指令執行一個類(類中的main方法)時,會從classpath中進行查找這個類。
指定classpath的方式一:
設定環境變量CLASSPATH,多個路徑之間使用英文的分号隔開,也可以指定為jar包路徑。
示例:CLASSPATH=c:/myclasses/;c/mylib/aa.jar;c:/mylib/bb.jar;.
注意:在Windows中不區分大小寫,是以指定的環境變量名為classpath或是ClassPath都一樣。
指定classpath的方式二:
在執行java指令時通過-classpath參數指定。
示例:java -classpath c:/myclasses/;c:/mylib/aa.jar cn.itcast.MainApp
注意:這樣就會隻是用這個參數指定的classpath,找不到類就報錯,不會使用CLASSPATH環境變量!
指定classpath時各個路徑的順序:
試驗的結論是 按classpath中指定的順序,先從前面的路徑中查找,如果找不到,在從下一個路徑中查找,直到找到類位元組碼或是報NoClassDefFoundError。
另外一種指定類路徑方式:
把類位元組碼檔案打成jar包,并放到JRE的lib/ext/目錄下,這樣在執行時就可以直接找到這個類而不需要指定classpath了。
類加載器與classpath
從上一個文章中我們知道了類加載器預設使用三個:
1,Bootstrap ClassLoader,啟動類加載器,負責加載核心Class(即所有java.*開頭的Class)。
2,Extension ClassLoader,擴充類加載器,負責加載存放在JRE的lib/ext/目錄下的jar包中的Class。
3,Application ClassLoader,應用程式類加載器,負責加載應用程式自身的類(CLASSPATH目錄中的Class)。
分析ExtClassLoader
Extension ClassLoader負責加載擴充類路徑中的類(預設為JRE的lib/ext/目錄) ,也就是說隻要把jar包放到這個目錄中,就可以直接使用裡面的類位元組碼而不需要指定classpath !注意這要求一定要在這個目錄中放jar包,直接把.class檔案放到這個目錄中不行。分析一下源碼(sun.misc.Launcher$ExtClassLoader類):
Application ClassLoader負責加載CLASSPATH目錄中的Class ,也就是說classpath是給這個類加載器用的。分析一下源碼(sun.misc.Launcher$AppClassLoader類):
當AppClassLoader遇上ExtClassLoader
如果JRE的lib/ext/目錄下的jar包有某個類,我們指定的classpath中也有這個類,會怎麼樣呢?想想類加載查找類位元組碼的政策!結論是會執行lib/ext/xx.jar中的類! 因為類加載器使用委托模式進行類加載,并且ExtClassLoader是AppClassLoader的上級,是以AppClassLoader會先讓ExtClassLoader加載。如果父的類加載器沒有找到,自己才會加載。
結論:
1,把jar包放到擴充類路徑中就可以直接使用其中的類(預設是JRE的lib/ext/目錄)
2,classpath是給AppClassLoader配置的。
3,如果擴充類路徑中有某個類,classpath中也有這個類,則會使用擴充類路徑中的類。
http://www.tuicool.com/articles/bQFnqmi