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

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

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

    Oo緣來是你oO


    posts - 120,comments - 125,trackbacks - 0
    ????????????????????????????? 在Java中使用循環(huán)定義會出現(xiàn)哪些問題 ?

    ??????????????????????????????????????????????
    馬嘉楠 ??????? 2006-10-19


    在上一篇文章《 inconstant constants ( 變化無常的常量 ) ? 》的基礎(chǔ)上,我們再來研究一下在 Java 中使用循環(huán)定義會出現(xiàn)哪些問題

    老規(guī)矩,代碼伺候 ^+^

    例1:

    public class
    ClassX{
    ???public?static?final?intX?=?2*
    ClassY.Y;
    }

    public?class
    ClassY{
    ???public?static?final?intY?=ClassZ.Z+?1
    ;
    }

    public class ?ClassZ? extends
    ClassX{
    ???public?static?final?int?Z=?X?+?3
    ;
    }

    public class?
    ClassTest{
    ???public?static?void
    main(String[]?args){
    ??????System.out.println(ClassX.X
    + ClassY.Y +
    ClassZ.Z);
    ???}
    }


    代碼中的static final變量X,Y,Z,循環(huán)定義。

    你可以先想一下,這個值會是多少?看看與實(shí)際結(jié)果是否一致。

    輸出結(jié)果:


    現(xiàn)在對ClassTest.java進(jìn)行一點(diǎn)修改,如下:

    例2:

    public?class
    ClassTest{
    ???public?staticvoid
    main(String[]?args){
    ??????System.out.println(ClassZ.Z
    + ClassY.Y +
    ClassX.X);
    ???}
    }

    兩次的輸出結(jié)果會一樣么?
    我既然這么問了,你肯定會說不一樣,那你知道原因么?你知道這次的輸出結(jié)果么?
    可以先思考一下。

    輸出結(jié)果:


    讓我來告訴你這是怎么回事。

    我們可以看見,對于三個staitc final 變量 X,Y,Z,他們的初始化表達(dá)式是循環(huán)定義的。在編譯期間不能確定它們的值,所以它們是運(yùn)行期間常量( runtime constants ),編譯器不會進(jìn)行常量替換。
    而且每個表達(dá)式的計(jì)算將會依賴于類裝載的順序。

    例如,為了計(jì)算出例1中的 ClassTest 結(jié)果,我們可以預(yù)見,ClassX 是第一個被裝載的類,但是第一個完成初始化的類卻是 ClassZ.

    讓我們一步一步看看都發(fā)生了什么。

    1.???X = 2 * ClassY.Y;??????計(jì)算X,需要知道ClassY.Y的值,下一步計(jì)算Y值
    2.???Y = ClassZ.Z + 1;??????計(jì)算Y,需要知道ClassZ.Z的值,下一步計(jì)算Z值
    3.???Z = X + 3;??????????????? 計(jì)算Z,需要知道X的值,而此時X的值還沒有被計(jì)算出來(又轉(zhuǎn)回來了,居然是個圈,呵呵^+^),所以我們使用X的默認(rèn)值0。

    因此:
    ??????Z = 3;
    ??????Y = 4;
    ??????X = 8;

    所以 ClassX.X + ClassY.Y + ClassZ.Z? =? 15

    例2當(dāng)中,也是同一道理
    不同的是,ClassZ是第一個被裝載的類,ClassX是第一個完成初始化的類
    1. Z = X + 3;
    2. X = 2 * ClassY.Y;
    3. Y = ClassZ.Z + 1;(此時使用Z的默認(rèn)值0)

    因此:
    ??????Y = 1;
    ??????X = 2;
    ??????Z = 5;

    所以 ClassZ.Z + ClassY.Y + ClassX.X = 8

    只是簡單的改變的輸出順序,結(jié)果卻截然不同。哪一個才是你想要得結(jié)果呢?

    我的例子看起來有點(diǎn)挖空心思鉆牛角尖,但是在大型項(xiàng)目當(dāng)中,也許就會出現(xiàn)與例子當(dāng)中相同的循環(huán)定義,如果真的存在的話,那么在紛繁的代碼當(dāng)中想要發(fā)現(xiàn)循環(huán)定義可不是件容易的事情。

    如果獨(dú)立看每一個定義的話,似乎都可以進(jìn)行常量替換,看不出任何問題。但是這樣的代碼在不久的將來就會引發(fā)問題,而且不易被我們所察覺。

    在你的應(yīng)用程序當(dāng)中不經(jīng)意的代碼改變(例如示例代碼中我們只是改變了輸出順序,卻產(chǎn)生了截然不同的結(jié)果),就會導(dǎo)致不同的類裝載順序和計(jì)算順序,或者在并發(fā)的線程調(diào)度中,可能也會導(dǎo)致致不同的類裝載順序和計(jì)算順序。不幸的是,大多數(shù)編譯器不認(rèn)為這種代碼是錯誤,也不會對編程人員給出任何警告。

    我只是講了一下循環(huán)定義會引發(fā)的問題,我暫時也想不出什么好的解決辦法,只能在編程的過程當(dāng)中盡量注意啦。


    注:有錯誤請告訴我,非常感謝!



    馬嘉楠
    jianan.ma@gmail.com

    posted on 2006-10-19 10:58 馬嘉楠 閱讀(2022) 評論(4)  編輯  收藏 所屬分類: Java

    FeedBack:
    # re: 在java中使用循環(huán)定義會出現(xiàn)哪些問題?
    2006-10-19 12:56 | 尚元秋
    是不是很好玩啊  回復(fù)  更多評論
      
    # re: 在java中使用循環(huán)定義會出現(xiàn)哪些問題?
    2006-10-19 17:44 | rainsf
    很無聊的問題  回復(fù)  更多評論
      
    # re: 在java中使用循環(huán)定義會出現(xiàn)哪些問題?
    2006-10-19 21:13 | Web 2.0 技術(shù)資源
    誰這樣寫代碼~ 就槍斃他!  回復(fù)  更多評論
      
    # re: 在java中使用循環(huán)定義會出現(xiàn)哪些問題?
    2007-01-09 10:53 | 菜包
    又學(xué)到鳥  回復(fù)  更多評論
      
    主站蜘蛛池模板: 1区2区3区产品乱码免费| 国产免费看插插插视频| 亚洲人成网站999久久久综合| 日韩一区二区三区免费体验| 久久www免费人成看国产片| 亚洲高清无在码在线电影不卡 | 久久国内免费视频| 国产亚洲精品第一综合| 亚洲AV无一区二区三区久久| 成人五级毛片免费播放| 中文字幕的电影免费网站| 亚洲免费网站在线观看| 中文字幕亚洲不卡在线亚瑟| 午夜国产精品免费观看 | 日韩免费无砖专区2020狼| 最近免费字幕中文大全| 在线观看日本亚洲一区 | 日韩精品亚洲专区在线影视| 亚洲午夜精品一区二区| 又色又污又黄无遮挡的免费视| 久久99精品视免费看| 国产亚洲美女精品久久久久| 久久久亚洲欧洲日产国码二区| 免费看国产精品麻豆| 无码乱肉视频免费大全合集| 巨胸喷奶水www永久免费| 亚洲欧美日韩综合俺去了| 亚洲AV色香蕉一区二区| 亚洲国产高清精品线久久| 日韩免费a级毛片无码a∨ | 亚洲另类无码一区二区三区| 亚洲网站在线观看| 亚洲国产高清精品线久久| 免费看的成人yellow视频| 国产电影午夜成年免费视频| a级毛片黄免费a级毛片| 青娱乐在线免费观看视频| 亚洲av无码专区亚洲av不卡 | 久久综合给合久久国产免费| yellow视频免费看| 精品国产亚洲一区二区三区在线观看|