91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java枚舉:小小enum,優雅而干凈

發布時間:2020-07-12 03:31:04 來源:網絡 閱讀:163 作者:沉默王二 欄目:編程語言

《Java編程思想》中有這么一句話:“有時恰恰因為它,你才能夠‘優雅而干凈’地解決問題”——這句話說的是誰呢?就是本篇的主角——枚舉(Enum)——大家鼓掌了。

在之前很長時間一段時間里,我都不怎么用枚舉,因為總感覺它沒什么用處——這其實就是“自我認知”的短見。當一個人一直蹲在自己的深井里而不敢跳出來的話,那他真的只能看到井口那么大點的天空

隨著時間的推移,我做的項目越來越多,和枚舉見面的機會也越來越多,于是我就漸漸地對它越來越有興趣,研究得多了,才發現原來枚舉如此的優秀。

1)枚舉的常規用法

一個精簡的枚舉非常的干凈優雅,見下例。

public enum Chenmo {
    WANGER, WANGSAN, WANGSI
}

我們為沉默枚舉創建了三個值,分別是王二、王三、王四。這段代碼實際上調用了3次Enum(String name, int ordinal)(ordinal單詞的意思為順序),也就是:

new Enum<Chenmo>("WANGER", 0);
new Enum<Chenmo>("WANGSAN", 1);
new Enum<Chenmo>("WANGSI", 2);

我們來遍歷輸出一下枚舉:

for (Chenmo e : Chenmo.values()) {
    System.out.println(e);
}
//輸出
//WANGER
//WANGSAN
//WANGSI

2)作為switch的判斷條件

使用枚舉作為switch語句判斷條件能讓我們的代碼可讀性更強,示例如下。

Chenmo key = Chenmo.WANGER;
switch (key) {
case WANGSI:
    System.out.println("今天我送出一個CSDN大鼠標墊");
    break;
case WANGSAN:
    System.out.println("今天我被坑一個CSDN學院年卡");
    break;
default:
    System.out.println("今天我一邊高興,一邊失落");
    break;
}

在通過case關鍵字判斷的時候,可以直接使用枚舉值,非常簡潔。另外,在編譯期間限定類型,可以有效的避免越界的情況——字符串常量類型在作為switch判斷條件的時候很容易因為誤寫而發生越界問題。

3)枚舉實現單例

《Effective Java》一書中對使用枚舉實現單例的方式推崇備至:

使用枚舉實現單例的方法雖然還沒有廣泛采用,但是單元素的枚舉類型已經成為實現Singleton的最佳方法。

我覺得“雖然還沒有廣泛采用”幾個字可以去掉了,時至今日,大家應該都知道:使用枚舉實現單例是一種非常好的方式。

先來看“雙重校驗鎖”實現的單例:

public class SingleTon2 {

     // 私有化構造方法
    private SingleTon2() {
    };

    private static volatile SingleTon2 singleTon = null;

    public static SingleTon2 getInstance() {

        // 第一次校驗
        if (singleTon == null) {
            synchronized (SingleTon2.class) {
                // 第二次校驗
                if (singleTon == null) {
                    singleTon = new SingleTon2();
                }
            }
        }
        return singleTon;
    }
}

再來看枚舉實現的單例:

public enum SingleTon {

     INSTANCE;

    public void method() {
        System.out.println("我很快樂!");
    }
}

不比不知道,一比嚇一跳啊!枚舉方式的單例簡單到爆——為了不至于看起來太過精簡,我還加了一個輸出“我很快樂”的方法。

枚舉實現的單例可輕松地解決兩個問題:

①、線程安全問題。因為Java虛擬機在加載枚舉類的時候,會使用ClassLoader的loadClass方法,這個方法使用了同步代碼塊來保證線程安全。

②、避免反序列化破壞單例。因為枚舉的反序列化并不通過反射實現。

4)枚舉可與數據庫交互

我們可以配合Mybatis將數據庫字段轉換為枚舉類型。現在假設有一個數據庫字段check_type的類型如下:

`check_type` int(1) DEFAULT NULL COMMENT '檢查類型(1:未通過、2:通過)',

它對應的枚舉類型為CheckType,代碼如下:

public enum CheckType {
    NO_PASS(0, "未通過"), PASS(1, "通過");
    private int key;

    private String text;

    private CheckType(int key, String text) {
        this.key = key;
        this.text = text;
    }

    public int getKey() {
        return key;
    }

    public String getText() {
        return text;
    }

    private static HashMap<Integer,CheckType> map = new HashMap<Integer,CheckType>();
    static {
        for(CheckType d : CheckType.values()){
            map.put(d.key, d);
        }
    }

    public static CheckType parse(Integer index) {
        if(map.containsKey(index)){
            return map.get(index);
        }
        return null;
    }
}

CheckType枚舉類比我們剛開始見到的那個Chenmo枚舉類要復雜一些。

第一,CheckType新添加了構造方法,還有兩個字段,key為int型,text為String型。

第二,CheckType中有一個public static CheckType parse(Integer index)方法,可將一個Integer通過key的匹配轉化為枚舉類型。

那么現在,我們可以在Mybatis的配置文件中使用typeHandler將數據庫字段轉化為枚舉類型。

<resultMap id="CheckLog" type="com.entity.CheckLog">
  <id property="id" column="id"/>
  <result property="checkType" column="check_type" typeHandler="com.CheckTypeHandler"></result>
</resultMap>

其中checkType字段對應的類如下:

public class CheckLog implements Serializable {

    private String id;
    private CheckType checkType;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public CheckType getCheckType() {
        return checkType;
    }

    public void setCheckType(CheckType checkType) {
        this.checkType = checkType;
    }
}

CheckTypeHandler轉換器的類源碼如下:

public class CheckTypeHandler extends BaseTypeHandler<CheckType> {

    @Override
    public CheckType getNullableResult(ResultSet rs, String index) throws SQLException {
        return CheckType.parse(rs.getInt(index));
    }

    @Override
    public CheckType getNullableResult(ResultSet rs, int index) throws SQLException {
        return CheckType.parse(rs.getInt(index));
    }

    @Override
    public CheckType getNullableResult(CallableStatement cs, int index) throws SQLException {
        return CheckType.parse(cs.getInt(index));
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int index, CheckType val, JdbcType arg3) throws SQLException {
        ps.setInt(index, val.getKey());
    }
}

CheckTypeHandler 的核心功能就是調用CheckType枚舉類的parse()方法對數據庫字段進行轉換。

5)枚舉會比靜態常量更消耗內存嗎?

說完枚舉最常用的4個知識點后,我們來討論一下“枚舉會比靜態常量更消耗內存嗎?”這個話題——知乎上有人問這樣的問題,還有很多人參與回答。

按我的理解,問這個問題的人就好像是在問“0.000,001”比“0.000,000,99”大嗎?你說是嗎?


上一篇:如果有人再問你 Java 的反射,把這篇文章扔給他

下一篇:Java注解(Annotation):請不要小看我!

微信搜索「*沉默王×××免費視頻**」獲取 500G 高質量教學視頻(已分門別類)。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

灵璧县| 达孜县| 乌兰浩特市| 兴化市| 韩城市| 越西县| 平顶山市| 宜宾县| 浙江省| 大姚县| 高州市| 大田县| 碌曲县| 石台县| 叙永县| 博客| 常宁市| 玉屏| 新乐市| 穆棱市| 安陆市| 合作市| 囊谦县| 朔州市| 马鞍山市| 石城县| 安阳市| 台山市| 揭东县| 光泽县| 阳城县| 平泉县| 兰坪| 兴文县| 龙岩市| 北辰区| 海南省| 侯马市| 湖北省| 景洪市| 乌拉特中旗|