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

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

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

    posts - 8,  comments - 6,  trackbacks - 0

    1.2  計(jì)數(shù):使用枚舉 

    Java5+

    大多數(shù)應(yīng)用程序需要記錄一個(gè)值的有限集—— 即應(yīng)用程序中表示一組選擇或狀態(tài)的常量。一種常見(jiàn)的Java編程慣例是使用static int變量來(lái)表示這些值。然后讓程序通過(guò)比較這些值和其他變量的值來(lái)做出決定。盡管核心Java API本身也采用這種慣例,但它很可能導(dǎo)致嚴(yán)重的問(wèn)題!下面是一個(gè)有關(guān)水果信息的示例。該示例給出了使用int變量來(lái)表示枚舉數(shù)據(jù)時(shí)會(huì)出現(xiàn)的一些問(wèn)題。
    public class FruitConstants {
    // this is not such a good practice
    public static final int APPLE = 1;
    public static final int ORANGE = 2;
    public static final int GRAPEFRUIT = 3;
    public static final int BANANA = 4;
    public static final int DURIAN = 5;
    public static final int CITRUS = 6;
    public static final int SWEET = 7;
    public static final int SMELLY = 8;
    public static final int UNKNOWN = 9;

    public static int getCategory(int fruit) {
    switch(fruit) {
    case APPLE: case BANANA:
    return SWEET;
    case ORANGE: case GRAPEFRUIT:
    return CITRUS;
    case DURIAN:
    return SMELLY;
    }
    return UNKNOWN;
    }
    }

    其中,來(lái)自東南亞的水果榴蓮(Durian)具備“Sweet”和“Smelly”,但是這里的水果只能返回一個(gè)特點(diǎn),也就是說(shuō),所有的值只能是對(duì)應(yīng)單一的值而不是對(duì)應(yīng)多個(gè)值。另外一個(gè)主要的問(wèn)題是任何int值都可以傳遞給getCategory方法,無(wú)論它是否代表一個(gè)有效的水果。這可能導(dǎo)致細(xì)微的錯(cuò)誤,因?yàn)榫幾g器不關(guān)心是調(diào)用getCategory(SWEET)還是調(diào)用getCategory(42)。并且如果整型常量的值發(fā)生了變化,getCategory(3)顯示的將不再是正確的信息!
    另一個(gè)問(wèn)題是使用水果和類(lèi)別的int值并無(wú)區(qū)別—— 它們都只是普通的int值。通過(guò)簡(jiǎn)單地將類(lèi)別常量置于一個(gè)不同的類(lèi)中可以部分地解決水果和類(lèi)別分離的問(wèn)題,但是它們?nèi)灾皇莍nt值而不是類(lèi)型安全(typesafe)的,也就是沒(méi)能將getCategory的參數(shù)限制到一個(gè)固定的值集合。
    在Java 5中,有一個(gè)優(yōu)雅的解決方法:可以像在C語(yǔ)言中那樣創(chuàng)建枚舉類(lèi)型。這是一個(gè)新特性,它創(chuàng)建一個(gè)類(lèi),該類(lèi)包含一個(gè)所有它允許的實(shí)例清單。除了enum內(nèi)定義的實(shí)例外,不允許其他的實(shí)例。下面看一些enum的示例:
    enum Fruit {APPLE, ORANGE, GRAPEFRUIT, BANANA, DURIAN}
    enum FruitCategory {SWEET, CITRUS, SMELLY, UNKNOWN}
    enum Dessert {PIE, CAKE, ICECREAM, BROWNIE}

    以上每個(gè)例子均定義了一組不同的枚舉元素(選擇)。這樣做的好處是不會(huì)將Fruit值與其他類(lèi)型的相混合或相混淆。對(duì)待每個(gè)enum就好像它是一個(gè)不同的類(lèi)一樣。不能將FruitCategory作為一個(gè)參數(shù)傳遞給一個(gè)期望Dessert的值方法,也不能傳遞一個(gè)int值。下面擴(kuò)展Fruit enum以包含最初的FruitConstants類(lèi)具有的功能:
    public enum Fruit {
    APPLE, ORANGE, GRAPEFRUIT, BANANA, DURIAN;

    public static FruitCategory getCategory(Fruit fruit) {
    switch(fruit) {
    case APPLE: case BANANA:
    return FruitCategory.SWEET;
    case ORANGE: case GRAPEFRUIT:
    return FruitCategory.CITRUS;
    case DURIAN:
    return FruitCategory.SMELLY;
    }
    return FruitCategory.UNKNOWN;
    }
    }


    可以看出一個(gè)enmu也可以像一個(gè)類(lèi)那樣定義方法。現(xiàn)在的getCategory方法采用Fruit作為參數(shù),并且只允許使用enum中定義的值。接下來(lái)這個(gè)代碼段將引起編譯錯(cuò)誤,而不會(huì)出現(xiàn)調(diào)用最初的未受保護(hù)的getCategory方法時(shí)出現(xiàn)的運(yùn)行時(shí)異常:
    Fruit.getCategory(Dessert.PIE); // compile error
    Fruit.getCategory(10); // compile error

    如果每種水果管理它自己的類(lèi)別將會(huì)更好,因此為了完善Fruit類(lèi),將刪除getCategory的水果參數(shù)并使該方法為每個(gè)enum狀態(tài)返回不同的值。通過(guò)創(chuàng)建一個(gè)適用于所有值的抽象的getCategory方法并對(duì)每個(gè)enum以不同的方式重寫(xiě)它,可以完成此操作。它非常類(lèi)似于為每個(gè)枚舉值編寫(xiě)一個(gè)不同的子類(lèi),并讓每個(gè)這樣的子類(lèi)重寫(xiě)抽象的方法。
    public enum Fruit {
    APPLE
    { FruitCategory getCategory() {return FruitCategory.SWEET;} },
    ORANGE
    { FruitCategory getCategory() {return FruitCategory.CITRUS;} },
    GRAPEFRUIT
    { FruitCategory getCategory() {return FruitCategory.CITRUS;} },
    BANANA
    { FruitCategory getCategory() {return FruitCategory.SWEET;} },
    DURIAN
    { FruitCategory getCategory() {return FruitCategory.SMELLY;} };

    abstract FruitCategory getCategory();
    }


    一旦創(chuàng)建一個(gè)類(lèi)似這樣的enum,就可以像對(duì)待其他對(duì)象那樣來(lái)對(duì)待APPLE值(使用靜態(tài)的Fruit.APPLE引用),并且可以調(diào)用它的getCategory方法來(lái)得到它的相應(yīng)類(lèi)別。現(xiàn)在可以為上面的類(lèi)添加一個(gè)main方法來(lái)說(shuō)明如何使用新的Fruit enum:
    public static void main(String[] args) {
    Fruit a = Fruit.APPLE;
    // toString() returns "APPLE"
    System.out.println ("The toString() for a: " + a);
    // getCategory() returns "SWEET"
    System.out.println ("a.getCategory() is: " + a.getCategory());
    for (Fruit f : Fruit.values()) {
    System.out.println ("Fruit is: " + f);
    }
    }

    正如代碼中所示的那樣,可以使用values方法來(lái)迭代enum內(nèi)的所有值。enum的toString方法將會(huì)返回一個(gè)String,它具有和值相同的名字。使用enum而不是int來(lái)表示狀態(tài),可以使代碼具有更好的可讀性和更強(qiáng)的防錯(cuò)性。它明確地定義了一個(gè)特殊的枚舉狀態(tài)的所有值并可以防止有人使用不正確的值。


    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    留言簿(1)

    隨筆分類(lèi)

    隨筆檔案

    文章分類(lèi)

    文章檔案

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    主站蜘蛛池模板: 亚州免费一级毛片| 国产一级淫片免费播放电影| 亚洲精华国产精华精华液| 亚洲?V乱码久久精品蜜桃| 手机看片国产免费永久| 亚洲人成7777| 亚洲中文字幕在线乱码| a级毛片无码免费真人| 丝瓜app免费下载网址进入ios| 久久亚洲私人国产精品| 国产91久久久久久久免费| 91精品啪在线观看国产线免费| 美女被免费网站在线视频免费 | 美女被免费视频网站a| 亚洲av色影在线| 国产成人免费a在线资源| 日本一区二区免费看| 色噜噜的亚洲男人的天堂| 亚洲日本va午夜中文字幕一区| 国产免费观看黄AV片| **真实毛片免费观看| www成人免费观看网站| 亚洲一区二区三区高清不卡| 亚洲AV无码成人专区片在线观看 | 大学生高清一级毛片免费| 成人无码WWW免费视频| 免费无码专区毛片高潮喷水| 亚洲人成影院77777| 亚洲AV无码成人专区片在线观看| 免费在线观看黄色毛片| 免费观看毛片视频| 国内精品乱码卡1卡2卡3免费| 中国一级特黄的片子免费| 看亚洲a级一级毛片| 亚洲一区二区三区乱码在线欧洲| 久久精品国产亚洲精品2020| 亚洲日本va在线视频观看| 亚洲国产精品专区在线观看| 免费观看大片毛片| 好爽…又高潮了毛片免费看| 99久久久国产精品免费无卡顿 |