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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

实在抵不住张老师的诱惑,又跳坑了

發(fā)布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实在抵不住张老师的诱惑,又跳坑了 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目在 這里?。真是慚愧啊。前天才給 朋友說張老師的題目太長,我沒有沒有本事一目十行立馬解答,還是不玩兒了。而且明天就要做演示了,后天就要交作業(yè)了,領(lǐng)導(dǎo)還鬧著要我陪她溜冰。但后來忍不住看了張老師的帖子,不能自己地想知道答案啊。心里那個癢啊。偏偏各位老大憤怒聲討張老師,就是不給我們小菜鳥們一個爽快的答案。我那個悶騷啊,難以言表。終于對不起朋友,對不起公司,對不起教授,對不起領(lǐng)導(dǎo),調(diào)出了我心愛的svn,來了一把svn -co http://svn.apache.org/repos/asf/ant/core/tags/ANT_165(因為我用ANT 1.6.5)???#xff0c;后來發(fā)現(xiàn)這一步純屬多事。嗯,沒有搞出最后答案,但我已經(jīng)沒有興趣了。目前的發(fā)現(xiàn)就算拋磚引玉吧:

張老師說: 從第一行打印的內(nèi)容上可以看到:AuxiliaryClass類的類裝載器為MainClass。這個結(jié)果與我的預(yù)期不同,因為按照類加載器的委托機(jī)制,MailClass類加載器將先委托其父級類裝載器AppClassLoader加載AuxiliaryClass,而AuxiliaryClass所在的目錄f:/project已經(jīng)在第6步中加入到了Classpath環(huán)境變量當(dāng)中,AppClassLoader可以成功加載AuxiliaryClass,所以,第一行打印出來的類裝載器應(yīng)該是AppClassLoader。

其實囁,這個結(jié)果和張老師的預(yù)期是一樣的。委托機(jī)制仍然在起作用。沒法不起啊。源碼說話:
01: protected synchronized Class loadClass (String name , boolean resolve ) throws ClassNotFoundException {
02:???????? // First, check if the class has already been loaded
03:???????? Class c = findLoadedClass (name ) ;
04:???????? if (c = = null ) {
05:???????????????? try {
06:???????????????????????? if (parent ! = null ) {
07:???????????????????????????????? c = parent . loadClass (name , false ) ;
08:???????????????????????? } else {
09:???????????????????????????????? c = findBootstrapClass0 (name ) ;
10:???????????????????????? }
11:???????????????? } catch (ClassNotFoundException e ) {
12:???????????????????????? // If still not found, then invoke findClass in order
13:???????????????????????? // to find the class.
14:???????????????????????? c = findClass (name ) ;
15:???????????????? }
16:???????? }
17:???????? if (resolve ) {
18:???????????????? resolveClass (c ) ;
19:???????? }
20:???????? return c ;
21: }

注意第07行。只要被裝載的類沒有被裝載過,parent.loadClass()就一定會被調(diào)用。 我們最后看到的是MainClass,那唯一的結(jié)論就是ClassNotFoundException被拋出。第11到第14行被執(zhí)行??墒俏覀冊贑LASSPATH里加入了到AuxiliaryClass的路徑啊!張老大可是做了實驗的。還好,福爾摩斯老大的話響起來:排除所有不可能的東東。剩下的看起來再不可能發(fā)生也是真相。不過呢,人見人耐的高爺爺也說過:小心了,俺只證明了這個算法正確,還沒有運(yùn)行程序來驗證。所以俺決定繼續(xù)下去,找點證據(jù)。于是我在MainClass里添加了下面這個方法:

23:???? protected synchronized Class loadClass(String className, boolean resolveClass) throws ClassNotFoundException {
24:???????? // Ask the VM to look in its cache.
25:???????? Class loadedClass = findLoadedClass(className);
26:???????? // search in getParent() if not found
27:???????? if (loadedClass == null) {
28:???????????????? System.out.println("loaded class is null");
29:???????????????? try {
30:???????????????????????? if (getParent() == null) {
31:???????????????????????????????? System.out.println("getParent() is null, class name is "+className);
32:???????????????????????????????? System.out.println("using system class loader "+getSystemClassLoader());
33:???????????????????????????????? //System.out.println("URLs: "+java.util.Arrays.asList(getSystemClassLoader().getURLs()));
34:???????????????????????????????? loadedClass = getSystemClassLoader().loadClass(className);
35:???????????????????????????????? System.out.println("now system class loader is: "+getSystemClassLoader());
36:???????????????????????????????? System.out.println("now loaded class is: "+loadedClass.getName());
37:???????????????????????? } else{
38:???????????????????????????????? System.out.println("using parent "+getParent()+" to load "+className);
39:???????????????????????????????? System.out.println("parent loader's urls: "+java.util.Arrays.asList(((java.net.URLClassLoader)getParent()).getURLs()));
40:???????????????????????????????? loadedClass = getParent().loadClass(className);
41:???????????????????????????????? System.out.println("getParent() is not null, getParent() loads class: "+loadedClass.getName());
42:???????????????????????? }
43:???????????????? } catch (ClassNotFoundException e) {
44:???????????????????????? // don't do anything.? Catching this exception is the normal protocol for
45:???????????????????????? // getParent() classloaders telling use they couldn't find a class.
46:???????????????????????? System.out.println("ClassNotFound by"+ getParent()+e);
47:???????????????????????? e.printStackTrace();
48:???????????????? }
49:
50:???????????????? // not findLoadedClass or by getParent().loadClass, try locally
51:???????????????? if (loadedClass == null) loadedClass = findClass(className);
52:???????? }
53:
54:???????? // resolve if required
55:???????? if (resolveClass) resolveClass(loadedClass);
56:???????? return loadedClass;
57:??? }????????????????????????????????????????????????????????????????????????????????????????

也就是說,我寫了一個自己的loadClass(),和ClassLoader里的幾乎一樣。唯一的區(qū)別是我加了不少調(diào)試句子。再運(yùn)行一下張老師的build.xml,除原來張老師提到的輸出以外,得到如下輸出:

[java] found loaded class: null
[java] loaded class is null
[java] using parent sun.misc.Launcher$AppClassLoader@65251c45 to load cn.it cast.AuxiliaryClass
[java] parent loader's urls: [file:/D:/tools/ant/lib/ant-launcher.jar]
[java] ClassNotFound bysun.misc.Launcher$AppClassLoader@65251c45java.lang.ClassNotFoundException: cn.itcast.AuxiliaryClass
[java] java.lang.ClassNotFoundException: cn.itcast.AuxiliaryClass
??????????????????????????????????????????????????????????????????????????????
到這個時候我可以肯定三件事了:

  • sun.misc.Launcher$AppClassLoader是被調(diào)用了的。
  • Classpath是被改動了的。AppClassLoader只能看到[file:/D:/tools/ant/lib/ant-launcher.jar]。也就是說,ANT把系統(tǒng)CLASSPATH里的值用ANT命令行里規(guī)定的-classpath里的值替換了。
  • 前面討論的ClassNotFoundException的確被拋出。
  • 嗯,這個顯然是ANT的問題。如果在run這個target里調(diào)用java這個task時加上fork="true",就可以看到如下的輸出。說明ANT新生成的JVM就沒有CLASSPATH的問題,因為新生成的JVM直接調(diào)用java, 不通過ant launcher。如果在eclipse里用代碼調(diào)用ANT的Main.main(),也可以看到張老師期望的輸出。說明用了自定義的ClassLoader,可以繞開這個問題。
    sun.misc.Launcher$AppClassLoader
    sun.misc.Launcher$ExtClassLoader

    那ANT為什么會改動CLASSPATH躡?這個俺就不知道了。所以我在開頭說我沒有找到最后答案。畢竟張老師問的是ANT造成這個結(jié)果的機(jī)制。不過我們可以肯定這個錯誤沒有發(fā)生在AntClassLoader和AntClassLoader2這兩個類里(我也許錯了)。也就是說,我很懷疑這個bug和ANT的classloader直接相關(guān)。

    所謂google在手,一個頂九。于是我找到了這個bug report. 看來張老師的確發(fā)現(xiàn)了ANT的一個bug。看來這個bug已經(jīng)在ant 1.7里被修復(fù)。造成bug的具體原因我還是不知道。不過這重要么?不重要么?ANT的一個bug而已,我想不出去了解這個bug的意義何在。我還有幾百個bug要修補(bǔ),幾百個feature要添加,幾百篇論文要讀。去關(guān)心ANT上百錯誤中一個對我來說無異于自虐。呵呵,見諒見諒,其實都是菜鳥水平不夠的托詞而已。我的動力很小,我的借口很多,我。。。。去陪領(lǐng)導(dǎo)溜冰樂。。

    其實這個問題的相關(guān)內(nèi)容其實也不深入,無關(guān)系統(tǒng)設(shè)計,無關(guān)算法,無關(guān)具體應(yīng)用。無非是某個編程錯誤而已。就算誰熟知ANT代碼,也是對ANT熟悉而已。就像我還對我們部門的代碼熟悉呢,不說明什么。但我還是做得很高興。典型的菜鳥特征啊。

    總結(jié)

    以上是生活随笔為你收集整理的实在抵不住张老师的诱惑,又跳坑了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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