<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

    ????????????????????? ????????? inconstant constants ( 變化無常的常量 )??
    ??????????????????????????????????????????
    ??????????????????????????????????????????
    馬嘉楠 ?????????????? 2006-10-18


    看到這個題目也許你會感到奇怪,會想我在胡說八道什么,一定又是起個怪異的名字,騙取點擊率。還請你耐心看完,如果你有所收獲,那么我很高興;如果你還是覺得上當了,那我繼續努力寫出點有用的東西,呵呵。

    其實我想了很久,也還是不知道起一個什么題目好,就套用了《 The Java Language Specification 》中的一個名詞“ inconstant constants”,我把他翻譯成“變化無常的常量

    注:部分內容在《 使用Java中的final變量需要注意的地方 》有提到,不過我轉載的原文不夠詳細深入,這才重新寫一下。

    我們還是來先看一段代碼,由代碼引出問題:

    public class ?ClassX?{
    ???
    public static final int ??X?? = ??? 2
    ?;
    }

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


    輸出結果:

    2

    結果是顯而易見的,這里需要說明的是:
    根據Java語言規范,對于java中的static final變量,如果用一個在編譯期間(complie time)可以計算出結果的表達式進行初始化,則用到此變量的地方會被該表達式的結果所替代。本例中,在編譯期間,ClassTest.main() 函數中 ClassX.X 將被2所替代。

    此時,在類ClassTest main()中不再有指向ClassX的動態鏈接,告訴ClassTest在運行的時候從ClassX獲得X的值,你可以通過使用javap反編譯器幫助你理解。

    1. 先編譯ClassTest.java文件
    ????????????javac ClassTest.java
    2. 使用javap
    ????????????javap -c ClassTest

    屏幕輸出:

    Complied?from?"ClassTest.java"
    public?class?ClassTest?extends?java.lang.Object{
    public?ClassTest();
    ???Code:
    ??????0:?aload_0
    ??????1:?invokespecial?????#1;?//Method?java/lang/Object."<init>
    ":()V
    ??????4:?return

    public?static?void?main(java.lang.String[]);
    ???Code:
    ??????0:?getstatic?????????#2;?//Field?java/lang/System.out:Ljava/io/PrintStream;
    ??????3:?iconst_2?
    ??????4:?invokevirtua??????#3;?//Method?java/io/PrintStream.println:(I)V
    ??????7:?return

    }


    可以看出,在調用System.out.println()之前,整數2已經被放在JVM的堆棧中,不再有指向ClassX.X的鏈接。如果此時,改變ClassX.X的值為1,并且重新編譯ClassX.X文件,但是并不重新編譯ClassTest.java文件,運行ClassTest,輸出結果仍然是2.

    這么做(常量替換)的一個原因是為了在編譯期間檢查switch case語句。switch語句中的每一個case都需要一個常量值,而且每兩個之間都不能相同,編譯器在編譯期間將會做檢查。

    如果用來給static final變量進行初始化的表達式,只能在運行時刻才可以計算出值,那么常量替換就不會發生.例如:

    public class ClassX?{
    ???public static?final?int?X?=?new?
    java.util.Random().nextInt();
    } ?


    ClassX 改變了,我們再來看一下Main.main():

    Complied?from?"ClassTest.java"
    public?class?ClassTest?extends?java.lang.Object{
    public?ClassTest();
    ???Code:
    ??????0:?aload_0
    ??????1:?invokespecial??????#1;?//Method?java/lang/Object."<init>
    ":()V
    ??????4:?return

    public?static?void?main(java.lang.String[]);
    ???Code:
    ??????0:?getstatic????????? #2;?//Field?java/lang/System.out:Ljava/io/PrintStream;
    ??????3:?getstatic????????? #3;?//Field?ClassX.X:I?
    ??????6:?invokevirtual??????#4;?//Method?java/io/PrintStream.println:(I)V
    ??????9:?return

    }


    此時我們可以看見有個引用指向了Field X。
    ( 如果把類ClassX改成Interface,仍然會出現上面的結果 )

    當然有方法可以使你避免出現"inconstant constants"問題。

    第一種方法:
    當你要聲明一個編譯期間常量的時候,一定要保證此變量不會或者不太可能改變,或者盡量少使用聲明為static final的變量。當然這只能治標不能治本,所以我推薦使用第二種方法。

    第二種方法:
    將變量聲明為private,同時聲明一個方法來獲得此變量的值

    // ClassX.java修改如下:?
    public class? ClassX?{
    ???private?static?final?int?X?=?2
    ;
    ???public? static int
    getX(){
    ??????return
    X;
    ???}
    }

    // ClassTest.java修改如下:?

    public?class? ClassTest{
    ???public?static?void?
    main(String[]?args){
    ??????System.out.println(ClassX.getX());
    ???}
    }


    此時再改變ClassX.X的值為1,重新編譯ClassX.java,而不編譯ClassTest,結果就會顯示1,而非2。這就避免了"inconstant constants"的問題。

    下一篇準備講一下
    《在java中使用循環定義會出現哪些問題?》


    ?



    馬嘉楠
    jianan.ma@gmail.com

    posted on 2006-10-18 16:27 馬嘉楠 閱讀(1616) 評論(5)  編輯  收藏 所屬分類: Java

    FeedBack:
    # re: inconstant constants(變化無常的常量)
    2006-10-18 21:24 | Flyingis
    下次記得可以將字體大小和格式稍調整一下,看起來舒服一點。

    寫的不錯啊。  回復  更多評論
      
    # re: inconstant constants(變化無常的常量)
    2006-10-18 22:08 | 馬嘉楠
    @Flyingis
    謝謝^+^

    我把字體改為3號了,確實看起來舒服很多
    問一下你得代碼和文字都用什么字體啊?
    我總是調不好  回復  更多評論
      
    # re: inconstant constants(變化無常的常量)
    2006-10-19 10:26 | Flyingis
    1.Word/OneNote直接粘貼過來的文章多余代碼比較多,格式會有問題,建議在粘貼過來后清除一下Word代碼。
    2.正文字號我一般用2號。
    3.漢字字體為宋體,英文字母為Verdana,全選然后選擇字體為Verdana即可,漢字默認就是宋體。  回復  更多評論
      
    # re: inconstant constants(變化無常的常量)
    2006-10-19 10:40 | 馬嘉楠
    我都是先在記事本上面寫的,寫得差不多了,粘貼過來,再做些修改就發布。

    今天凌晨開始就有問題了,開始不能登陸,之后就一直不能編輯,也許新版本升級?維護不用這么長時間吧。

    等可以編輯了,再來修改一下  回復  更多評論
      
    # re: inconstant constants(變化無常的常量)
    2006-10-19 11:21 | 馬嘉楠
    60天內閱讀排行
    增加了這個功能
    還是不能編輯,不知道還有什么東西改動

    應該貼一個公告出來啊  回復  更多評論
      
    主站蜘蛛池模板: 免费国产污网站在线观看不要卡| 亚洲AV无码乱码国产麻豆穿越| 久久国产精品亚洲综合| 色噜噜噜噜亚洲第一| 黄页网站免费观看| 免费福利资源站在线视频| 日本高清免费网站| 亚洲熟女精品中文字幕| 精品国产香蕉伊思人在线在线亚洲一区二区 | 中文字幕乱码亚洲无线三区| 国产一级特黄高清免费大片| 免费日本一区二区| 亚洲国产精品无码专区在线观看 | caoporm超免费公开视频| 亚洲精彩视频在线观看| 亚洲国产成人精品久久久国产成人一区二区三区综 | 67194国产精品免费观看| 亚洲精品中文字幕乱码影院| 免费a级毛片无码a∨性按摩| 69xx免费观看视频| 国产激情久久久久影院老熟女免费 | 九九免费精品视频在这里| 国内精品久久久久久久亚洲| AA免费观看的1000部电影| 国产午夜精品理论片免费观看| 亚洲国产精品久久久天堂| 国产青草视频免费观看97 | 亚洲天堂免费在线视频| 亚洲色欲色欱wwW在线| 亚洲AV成人精品网站在线播放| 亚洲视频免费观看| 美女无遮挡拍拍拍免费视频| 亚洲国产高清国产拍精品| 78成人精品电影在线播放日韩精品电影一区亚洲 | 亚洲日韩在线中文字幕综合| 亚洲女人影院想要爱| 国产一级特黄高清免费大片| 国产一级a毛一级a看免费人娇| 久久久久亚洲AV无码观看| 69成人免费视频| 老湿机一区午夜精品免费福利|