<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    DANCE WITH JAVA

    開發(fā)出高質(zhì)量的系統(tǒng)

    常用鏈接

    統(tǒng)計(jì)

    積分與排名

    好友之家

    最新評(píng)論

    一個(gè)有趣的現(xiàn)象

       無(wú)意間發(fā)現(xiàn)了一個(gè)有趣的現(xiàn)象。下邊是重現(xiàn)整個(gè)現(xiàn)象的過程。
    1,編寫一個(gè)接口
    package iface;
    public interface MyInt {

    }

    把這個(gè)接口做成一個(gè)jar包iface.jar
    2,編寫一個(gè)類
    package mylib;

    import iface.MyInt;

    public class MyJar {
        
    public static boolean isMyInterface(){
            
    return null==getMyInt();
        }

        
    public static MyInt getMyInt(){
            
    return null;
        }

    }

    同樣把這個(gè)類做成一個(gè)jar文件mylib.jar
    3,新建一個(gè)工程,加入兩個(gè)jar包。然后寫一個(gè)測(cè)試類
    import mylib.MyJar;

    public class Test {
        
    public static void main(String[] args) {
            System.out.println(MyJar.isMyInterface());
            System.out.println(MyJar.getMyInt());
        }

    }

    4,運(yùn)行得到結(jié)果:
    true
    null
    到這里一切正常,下邊開始不同的地方。
    5,把iface.jar從工程中移走,這時(shí)測(cè)試類出現(xiàn)編譯錯(cuò)誤,這是因?yàn)镸yJar.getMyInt()要返回一個(gè)MyInt類型的對(duì)象,而MyInt接口不存在。
    刪掉測(cè)試類的第二個(gè)println 變成這樣
    import mylib.MyJar;

    public class Test {
        
    public static void main(String[] args) {
            System.out.println(MyJar.isMyInterface());
        }

    }

    重新編譯,通過。運(yùn)行得到結(jié)果 :
    true
    8,分析:移走接口后導(dǎo)致測(cè)試類第二行println()中的代碼Myjar.getMyInt()編譯不過去,不能之行,是因?yàn)檎也坏組yInt接口
    但第一行能編譯,且能執(zhí)行,而第一行的代碼在內(nèi)部其實(shí)是調(diào)用第二行的,但依然能執(zhí)行成功。
    這就說同樣的函數(shù):MyJar.getMyInt()外部調(diào)用不能執(zhí)行,通過一個(gè)函數(shù)轉(zhuǎn)一下就能執(zhí)行,呵呵,挺有趣。
    感覺應(yīng)該是虛擬機(jī)的實(shí)現(xiàn)機(jī)制方面的原因。詳細(xì)情形還沒有確認(rèn)。

    posted on 2007-07-05 01:00 dreamstone 閱讀(1768) 評(píng)論(14)  編輯  收藏 所屬分類: jdk相關(guān)

    評(píng)論

    # re: 一個(gè)有趣的現(xiàn)象[未登錄] 2007-07-05 09:15 劉明

    估計(jì)可能在null==getMyInt();這里的時(shí)候,getMyInt()不存在,直接為null吧?大概,需要測(cè)試一下。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-05 09:38 dennis

    沒必要打包成jar都有這個(gè)現(xiàn)象,將MyInt.class刪除也一樣。
    MyInt從來沒有被連接過(link),僅僅是被嘗試裝載(load),而裝載MyInt類但是沒有使用是不會(huì)拋出NoClassDefFoundError的。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象[未登錄] 2007-07-05 09:45 劉明

    將iface.jar移走后,如果不重新編譯的話,程序依然能夠運(yùn)行,true null,(我直接用的類,沒打包)。其實(shí)當(dāng)你把iface.jar移走后沒有重新編譯,如果重新編譯就能看到會(huì)報(bào)錯(cuò)的(找不到MyJar)。你使用的應(yīng)該是舊的class文件。

    我估計(jì)可能getMyInt()都沒有執(zhí)行,找不到就為null了。

    要知道具體原因可能需要打開class文件具體查看一下了。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-05 09:56 dennis

    getMyInt()是肯定有執(zhí)行,不信你可以在getMyInt加個(gè)
    System.out.println("getMyInt()");
    看看,原因俺已經(jīng)說明了,更深入地請(qǐng)看《深入Java虛擬機(jī)》,常量池中的MyInt雖然被裝載(裝載失敗),但沒有使用,沒有被連接、解析并初始化,可以簡(jiǎn)單地把它當(dāng)成一個(gè)符號(hào)罷了  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 09:56 BeanSoft

    懶惰加載, 優(yōu)化過的代碼, JVM 會(huì)走捷徑.  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 11:25 李敏

    我沒有打包,而是直接運(yùn)行的。現(xiàn)在說說我的看法。


    1 編譯好的字節(jié)碼中可能儲(chǔ)存了信息。具體的我也說不出來... !--
    2 當(dāng)你 javac Test的時(shí)候,它先是自動(dòng)搜索當(dāng)前有無(wú)編譯好的字節(jié)碼,如果沒有話,才會(huì)重新編譯,所以它會(huì)從之前的字節(jié)碼中讀出信息來參與編譯。

    可以用一個(gè)方法來測(cè)試,就是在當(dāng)前的classpath下,刪除掉MyJar.class,MyInt.java更換一個(gè)package的時(shí)候,就會(huì)發(fā)現(xiàn),無(wú)法通過編譯!

    呵呵,不知道我的想法對(duì)你有沒有幫助!
      回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 12:37 dreamstone

    @dennis
    打包只是為了模擬一個(gè)需求。怎么能說沒被使用呢
    isMyInterface()是調(diào)用了getMyInt()的。
    執(zhí)行isMyInterface()沒問題,
    執(zhí)行g(shù)etMyInt()有問題。這個(gè)怎么解釋,呵呵  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 12:39 dreamstone

    @劉明
    你可以測(cè)試一下,是可以重新編譯的。至少在eclipse是可以的。
    你可以直接刪掉.class文件,讓他重新編譯出來  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 12:40 dreamstone

    @dennis
    相對(duì)比較贊同這個(gè)觀點(diǎn),不過為什么調(diào)用getMyInt()會(huì)出錯(cuò)呢。根本編譯不了。呵呵。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 12:42 dreamstone

    @BeanSoft
    好像不是,我取了字節(jié)碼看,還是有這個(gè)接口的。不過考慮可能是load失敗,但是判斷null==A的時(shí)候,根本不管是個(gè)什么什么東西,只要知道它不是null就直接得出結(jié)論。因?yàn)閚ull的==是比較特殊的。不過這也是猜測(cè),沒有有力的證明  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 12:46 dreamstone

    @李敏
    恩,我明白你的意思。不過我說的特殊點(diǎn)在這里:
    c是test b是isMyInterface() a是getMyInt()
    c調(diào)用b b調(diào)用a能成功
    c直接調(diào)用a不能成功。
    而且都是putlic static 的函數(shù),  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 13:04 dreamstone

    另外提供一個(gè)信息,同樣的代碼和執(zhí)行方式
    在ibm aix上使用ibm sdk得到的結(jié)果是不一樣的,就是執(zhí)行isMyInterface() 也出錯(cuò),呵呵。這個(gè)才是起因。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 17:03 dennis

    load失敗拋出錯(cuò)誤的時(shí)間,不同jdk實(shí)現(xiàn)不同,有的是一失敗就馬上給出NoClassDefFoundError,有的是延遲到使用該類的時(shí)候再報(bào)錯(cuò)。為什么不能調(diào)用getMyInt?編譯不能通過啊,編譯過程中編譯器會(huì)查找所有出現(xiàn)的符號(hào)是否存在。  回復(fù)  更多評(píng)論   

    # re: 一個(gè)有趣的現(xiàn)象 2007-07-06 17:04 dennis

    這個(gè)問題,你再看下《深入java虛擬機(jī)》連接和初始化那個(gè)章節(jié)就明了了  回復(fù)  更多評(píng)論   

    主站蜘蛛池模板: 日本不卡免费新一区二区三区| 亚洲国产成人无码AV在线 | 亚洲日韩国产成网在线观看| 国产精品免费福利久久| 亚洲人成无码网WWW| eeuss免费影院| 三上悠亚亚洲一区高清| 精品多毛少妇人妻AV免费久久| 亚洲一本大道无码av天堂| 国产乱子伦精品免费视频| 国产亚洲AV手机在线观看| 中国毛片免费观看| 亚洲AV日韩AV永久无码免下载| 国产成人精品一区二区三区免费| 亚洲av日韩av天堂影片精品| 24小时日本韩国高清免费| 亚洲五月丁香综合视频| 毛片a级毛片免费播放100| 人人狠狠综合久久亚洲| 最近中文字幕免费完整| 亚洲男人的天堂在线va拉文| 亚洲校园春色另类激情| 女性自慰aⅴ片高清免费| 免费VA在线观看无码| 亚洲中文字幕无码中文字在线| a毛片免费在线观看| 亚洲国产人成网站在线电影动漫 | 亚洲A∨午夜成人片精品网站| 一级做a爰片久久免费| 毛片在线免费视频| 亚洲字幕在线观看| 国产好大好硬好爽免费不卡| 亚洲黄色在线播放| 1000部夫妻午夜免费| 亚洲性无码AV中文字幕| 亚洲成AV人网址| 99re在线视频免费观看| 国产成人精品日本亚洲语音| 亚洲三级高清免费| 亚洲国语在线视频手机在线| 国产又大又粗又硬又长免费 |