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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java面试题28 牛客 下面有关java classloader说法错误的是?

發(fā)布時(shí)間:2023/12/10 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java面试题28 牛客 下面有关java classloader说法错误的是? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java面試題28 牛客 下面有關(guān)java classloader說法錯(cuò)誤的是?

A Java默認(rèn)提供的三個(gè)ClassLoader是BootStrap ClassLoader,Extension ClassLoader,App ClassLoader B ClassLoader使用的是雙親委托模型來搜索類的 C JVM在判定兩個(gè)class是否相同時(shí),只用判斷類名相同即可,和類加載器無關(guān) D ClassLoader就是用來動(dòng)態(tài)加載class文件到內(nèi)存當(dāng)中用的

蒙蔽樹下蒙蔽果,蒙蔽樹上你和我


Java語言系統(tǒng)自帶有三個(gè)類加載器:

??? Bootstrap ClassLoader 最頂層的加載類,主要加載核心類庫,%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通過啟動(dòng)jvm時(shí)指定-Xbootclasspath和路徑來改變Bootstrap ClassLoader的加載目錄。比如java -Xbootclasspath/a:path被指定的文件追加到默認(rèn)的bootstrap路徑中。我們可以打開我的電腦,在上面的目錄下查看,看看這些jar包是不是存在于這個(gè)目錄。
??? Extention ClassLoader 擴(kuò)展的類加載器,加載目錄%JRE_HOME%\lib\ext目錄下的jar包和class文件。還可以加載-D java.ext.dirs選項(xiàng)指定的目錄。
??? Appclass Loader也稱為SystemAppClass 加載當(dāng)前應(yīng)用的classpath的所有類。

我們上面簡(jiǎn)單介紹了3個(gè)ClassLoader。說明了它們加載的路徑。并且還提到了-Xbootclasspath和-D java.ext.dirs這兩個(gè)虛擬機(jī)參數(shù)選項(xiàng)。
加載順序?

我們看到了系統(tǒng)的3個(gè)類加載器,但我們可能不知道具體哪個(gè)先行呢?
我可以先告訴你答案

??? Bootstrap CLassloder
??? Extention ClassLoader
??? AppClassLoader

為了更好的理解,我們可以查看源碼。
看sun.misc.Launcher,它是一個(gè)java虛擬機(jī)的入口應(yīng)用。
?

public class Launcher {private static Launcher launcher = new Launcher();private static String bootClassPath =System.getProperty("sun.boot.class.path");public static Launcher getLauncher() {return launcher;}private ClassLoader loader;public Launcher() {// Create the extension class loaderClassLoader extcl;try {extcl = ExtClassLoader.getExtClassLoader();} catch (IOException e) {throw new InternalError("Could not create extension class loader", e);}// Now create the class loader to use to launch the applicationtry {loader = AppClassLoader.getAppClassLoader(extcl);} catch (IOException e) {throw new InternalError("Could not create application class loader", e);}//設(shè)置AppClassLoader為線程上下文類加載器,這個(gè)文章后面部分講解Thread.currentThread().setContextClassLoader(loader);}/** Returns the class loader used to launch the main application.*/public ClassLoader getClassLoader() {return loader;}/** The class loader used for loading installed extensions.*/static class ExtClassLoader extends URLClassLoader {}/*** The class loader used for loading from java.class.path.* runs in a restricted security context.*/static class AppClassLoader extends URLClassLoader {}


源碼有精簡(jiǎn),我們可以得到相關(guān)的信息。

Launcher初始化了ExtClassLoader和AppClassLoader。
??? Launcher中并沒有看見BootstrapClassLoader,但通過System.getProperty("sun.boot.class.path")得到了字符串bootClassPath,這個(gè)應(yīng)該就是BootstrapClassLoader加載的jar包路徑。

我們可以先代碼測(cè)試一下sun.boot.class.path是什么內(nèi)容。
?

System.out.println(System.getProperty("sun.boot.class.path"));

得到的結(jié)果

C:\Program Files\Java\jre1.8.0_91\lib\resources.jar; C:\Program Files\Java\jre1.8.0_91\lib\rt.jar; C:\Program Files\Java\jre1.8.0_91\lib\sunrsasign.jar; C:\Program Files\Java\jre1.8.0_91\lib\jsse.jar; C:\Program Files\Java\jre1.8.0_91\lib\jce.jar; C:\Program Files\Java\jre1.8.0_91\lib\charsets.jar; C:\Program Files\Java\jre1.8.0_91\lib\jfr.jar; C:\Program Files\Java\jre1.8.0_91\classes

可以看到,這些全是JRE目錄下的jar包或者是class文件。
ExtClassLoader源碼

如果你有足夠的好奇心,你應(yīng)該會(huì)對(duì)它的源碼感興趣

/** The class loader used for loading installed extensions.*/static class ExtClassLoader extends URLClassLoader {static {ClassLoader.registerAsParallelCapable();}/*** create an ExtClassLoader. The ExtClassLoader is created* within a context that limits which files it can read*/public static ExtClassLoader getExtClassLoader() throws IOException{final File[] dirs = getExtDirs();try {// Prior implementations of this doPrivileged() block supplied// aa synthesized ACC via a call to the private method// ExtClassLoader.getContext().return AccessController.doPrivileged(new PrivilegedExceptionAction<ExtClassLoader>() {public ExtClassLoader run() throws IOException {int len = dirs.length;for (int i = 0; i < len; i++) {MetaIndex.registerDirectory(dirs[i]);}return new ExtClassLoader(dirs);}});} catch (java.security.PrivilegedActionException e) {throw (IOException) e.getException();}}private static File[] getExtDirs() {String s = System.getProperty("java.ext.dirs");File[] dirs;if (s != null) {StringTokenizer st =new StringTokenizer(s, File.pathSeparator);int count = st.countTokens();dirs = new File[count];for (int i = 0; i < count; i++) {dirs[i] = new File(st.nextToken());}} else {dirs = new File[0];}return dirs;}......}


我們先前的內(nèi)容有說過,可以指定-D java.ext.dirs參數(shù)來添加和改變ExtClassLoader的加載路徑。這里我們通過可以編寫測(cè)試代碼。
?

System.out.println(System.getProperty("java.ext.dirs"));


結(jié)果如下:

C:\Program Files\Java\jre1.8.0_91\lib\ext;C:\Windows\Sun\Java\lib\ext

AppClassLoader源碼
?

/*** The class loader used for loading from java.class.path.* runs in a restricted security context.*/static class AppClassLoader extends URLClassLoader {public static ClassLoader getAppClassLoader(final ClassLoader extcl)throws IOException{final String s = System.getProperty("java.class.path");final File[] path = (s == null) ? new File[0] : getClassPath(s);return AccessController.doPrivileged(new PrivilegedAction<AppClassLoader>() {public AppClassLoader run() {URL[] urls =(s == null) ? new URL[0] : pathToURLs(path);return new AppClassLoader(urls, extcl);}});}......}


可以看到AppClassLoader加載的就是java.class.path下的路徑。我們同樣打印它的值。
?

System.out.println(System.getProperty("java.class.path"));


結(jié)果:

D:\workspace\ClassLoaderDemo\bin



這個(gè)路徑其實(shí)就是當(dāng)前java工程目錄bin,里面存放的是編譯生成的class文件。
好了,自此我們已經(jīng)知道了BootstrapClassLoader、ExtClassLoader、AppClassLoader實(shí)際是查閱相應(yīng)的環(huán)境屬性sun.boot.class.path、java.ext.dirs和java.class.path來加載資源文件的。

看到這里我們?nèi)菀字繟答案是正確的

ClassLoader翻譯過來就是類加載器,普通的java開發(fā)者其實(shí)用到的不多,但對(duì)于某些框架開發(fā)者來說卻非常常見。理解ClassLoader的加載機(jī)制,也有利于我們編寫出更高效的代碼。ClassLoader的具體作用就是將class文件加載到j(luò)vm虛擬機(jī)中去,程序就可以正確運(yùn)行了。但是,jvm啟動(dòng)的時(shí)候,并不會(huì)一次性加載所有的class文件,而是根據(jù)需要去動(dòng)態(tài)加載。想想也是的,一次性加載那么多jar包那么多class,那內(nèi)存不崩潰。

看完這句話我們主動(dòng)D也是正確的

ClassLoader用來加載class文件的。
??? 系統(tǒng)內(nèi)置的ClassLoader通過雙親委托來加載指定路徑下的class和資源。
??? 可以自定義ClassLoader一般覆蓋findClass()方法。
??? ContextClassLoader與線程相關(guān),可以獲取和設(shè)置,可以繞過雙親委托的機(jī)制。

看完這句話我們知道B也是沒問題

再來看看C

JVM在判定兩個(gè)class是否相同時(shí),不僅要判斷兩個(gè)類名是否相同,而且要判斷是否由同一個(gè)類加載器實(shí)例加載的。

所以答案為C

我是歌謠,如有不合理之處歡迎討論。一起學(xué)習(xí),共同成長(zhǎng)

閱讀目錄(置頂)(長(zhǎng)期更新計(jì)算機(jī)領(lǐng)域知識(shí))

閱讀目錄(置頂)(長(zhǎng)期更新計(jì)算機(jī)領(lǐng)域知識(shí))

閱讀目錄(置頂)(長(zhǎng)期科技領(lǐng)域知識(shí))

歌謠帶你看java面試題

總結(jié)

以上是生活随笔為你收集整理的java面试题28 牛客 下面有关java classloader说法错误的是?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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