深入理解 Java 枚舉 Enum 類型用法

枚舉(enum)讲岁,是指一個(gè)經(jīng)過(guò)排序的、被打包成一個(gè)單一實(shí)體的項(xiàng)列表阱洪。一個(gè)枚舉的實(shí)例可以使用枚舉項(xiàng)列表中任意單一項(xiàng)的值芬迄。枚舉在各個(gè)語(yǔ)言當(dāng)中都有著廣泛的應(yīng)用问顷,通常用來(lái)表示諸如顏色、方式禀梳、類別杜窄、狀態(tài)等等數(shù)目有限、形式離散算途、表達(dá)又極為明確的量塞耕。Java從JDK5開始,引入了對(duì)枚舉的支持

在枚舉出現(xiàn)之前嘴瓤,如果想要表示一組特定的離散值扫外,往往使用一些常量。例如:

package com.fhp.enumexample;
 
public class Entity {
    
    public static final int VIDEO = 1;//視頻
    public static final int AUDIO = 2;//音頻
    public static final int TEXT = 3;//文字
    public static final int IMAGE = 4;//圖片
    
    private int id;
    private int type;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }   
}

當(dāng)然纱注,常量也不僅僅局限于int型畏浆,諸如char和String等也是不在少數(shù)胆胰。然而狞贱,無(wú)論使用什么樣的類型,這樣做都有很多的壞處蜀涨。這些常量通常都是連續(xù)瞎嬉、有無(wú)窮多個(gè)值的量,而類似這種表示類別的量則是離散的厚柳,并且通常情況下只有有限個(gè)值氧枣。用連續(xù)的量去表示離散量,會(huì)產(chǎn)生很多問(wèn)題别垮。例如便监,針對(duì)上述的Entity類,如果要對(duì)Entity對(duì)象的type屬性進(jìn)行賦值,一般會(huì)采用如下方法:

Entity e = new Entity();
e.setId(10);
e.setType(2);

這樣做的缺點(diǎn)有:(1)代碼可讀性差烧董、易用性低毁靶。由于setType()方法的參數(shù)是int型的,在閱讀代碼的時(shí)候往往會(huì)讓讀者感到一頭霧水逊移,根本不明白這個(gè)2到底是什么意思预吆,代表的是什么類型。當(dāng)然胳泉,要保證可讀性拐叉,還有這樣一個(gè)辦法:

e.setType(Entity.AUDIO);

而這樣的話,問(wèn)題又來(lái)了扇商。這樣做凤瘦,客戶端必須對(duì)這些常量去建立理解,才能了解如何去使用這個(gè)東西案铺。說(shuō)白了廷粒,在調(diào)用的時(shí)候,如果用戶不到Entity類中去看看红且,還真不知道這個(gè)參數(shù)應(yīng)該怎么傳坝茎、怎么調(diào)。像是setType(2)這種用法也是在所難免暇番,因?yàn)樗耆戏ㄠ头牛皇敲總€(gè)人都能夠建立起用常量名代替數(shù)值,從而增加程序可讀性壁酬、降低耦合性的意識(shí)

(2)類型不安全次酌。在用戶去調(diào)用的時(shí)候,必須保證類型完全一致舆乔,同時(shí)取值范圍也要正確岳服。像是setType(-1)這樣的調(diào)用是合法的,但它并不合理希俩,今后會(huì)為程序帶來(lái)種種問(wèn)題吊宋。也許你會(huì)說(shuō),加一個(gè)有效性驗(yàn)證嘛颜武,但是璃搜,這樣做的話,又會(huì)引出下面的第(3)個(gè)問(wèn)題

(3)耦合性高鳞上,擴(kuò)展性差这吻。假如,因?yàn)槟承┰蚋菀椋枰薷腅ntity類中常量的值唾糯,那么,所有用到這些常量的代碼也就都需要修改——當(dāng)然,要仔細(xì)地修改移怯,萬(wàn)一漏了一個(gè)拒名,那可不是開玩笑的。同時(shí)芋酌,這樣做也不利于擴(kuò)展增显。例如,假如針對(duì)類別做了一個(gè)有效性驗(yàn)證脐帝,如果類別增加了或者有所變動(dòng)同云,則有效性驗(yàn)證也需要做對(duì)應(yīng)的修改,不利于后期維護(hù)

(4)常量作為參數(shù)時(shí)堵腹,是String炸站,int等弱類型,開發(fā)人員可以傳入沒有在常量接口里定義的值疚顷,這個(gè)問(wèn)題無(wú)法通過(guò)編譯器發(fā)現(xiàn)

(5)編譯時(shí)旱易,是直接把常量的值編譯到類的二進(jìn)制代碼里,常量的值在升級(jí)中變化后腿堤,需要重新編譯引用常量的類阀坏,因?yàn)槔锩娲娴氖桥f值

(6)如果常量類的構(gòu)造器不私有,無(wú)法限制開發(fā)員繼承/實(shí)現(xiàn)接口笆檀,開發(fā)員能夠在子接口里繼續(xù)添加常量.而這些常量可能得不到祖先層的支持

枚舉就是為了這樣的問(wèn)題而誕生的忌堂。它們給出了將一個(gè)任意項(xiàng)同另一個(gè)項(xiàng)相比較的能力,并且可以在一個(gè)已定義項(xiàng)列表中進(jìn)行迭代酗洒。枚舉(在Jave中簡(jiǎn)稱為enum)是一個(gè)特定類型的類士修。所有枚舉都是Java中的新類java.lang.Enum的隱式子類。此類不能手工進(jìn)行子類定義樱衷。一個(gè)簡(jiǎn)單的枚舉可以是這樣:

package com.fhp.enumexample;
 
public enum TypeEnum {
    VIDEO, AUDIO, TEXT, IMAGE
}

上面的Entity類就可以改成這樣:

package com.fhp.enumexample;
 
public class Entity {
    
    private int id;
    private TypeEnum type;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
        
    public TypeEnum getType() {
        return type;
    }
    public void setType(TypeEnum type) {
        this.type = type;
    }
}

在為Entity對(duì)象賦值的時(shí)候棋嘲,就可以這樣:

Entity e = new Entity();
e.setId(10);
e.setType(TypeEnum.AUDIO);

怎么看,都是好了很多矩桂。在調(diào)用setType()時(shí)沸移,可選值只有四個(gè),否則會(huì)出現(xiàn)編譯錯(cuò)誤耍鬓,因此可以看出阔籽,枚舉是類型安全的,不會(huì)出現(xiàn)取值范圍錯(cuò)誤的問(wèn)題牲蜀。同時(shí),客戶端不需要建立對(duì)枚舉中常量值的了解绅这,使用起來(lái)很方便涣达,并且可以容易地對(duì)枚舉進(jìn)行修改,而無(wú)需修改客戶端。如果常量從枚舉中被刪除了度苔,那么客戶端將會(huì)失敗并且將會(huì)收到一個(gè)錯(cuò)誤消息匆篓。枚舉中的常量名稱可以被打印,因此除了僅僅得到列表中項(xiàng)的序號(hào)外還可以獲取更多信息寇窑。這也意味著常量可用作集合的名稱鸦概,例如HashMap

基本enum特征

所有創(chuàng)建的枚舉類都繼承自抽象類 java.lang.Enum;

一個(gè)枚舉類,所有實(shí)例都要在第一句寫出以 甩骏,隔開窗市。 如果只有實(shí)例最后可以不加 ; 枚舉類因?yàn)槔^承了Enum,所以再不能繼承別的類饮笛,任何類也不能繼承枚舉類(構(gòu)造器默認(rèn)為private)

public enum Color {
    RED,
    BLUE,
    YELLOW,
    PURPLE
}

注意 :RED,BLUE 這些是由 enum Color類調(diào)用默認(rèn)private構(gòu)造器創(chuàng)建的實(shí)例對(duì)象咨察,和普通class相比只不過(guò)enum的實(shí)例對(duì)象只能在內(nèi)部創(chuàng)建。時(shí)刻記著他們是一個(gè)實(shí)例對(duì)象

枚舉類實(shí)例不能在外部 new 出來(lái) 福青,因?yàn)槊杜e類構(gòu)造器為private 一般也不用聲明private摄狱,默認(rèn)就是private,因?yàn)閑num實(shí)例只能在編譯期間enum類內(nèi)部被創(chuàng)建无午,但可以外部得到一個(gè)實(shí)例的引用

Color red  = Color.RED;
Color blue = Color.BLUE;

枚舉類的一些方法

  1. 使用枚舉元素 Color.RED 或者 red
  2. Color.values( ) 返回一個(gè)枚舉類數(shù)組媒役,數(shù)組元素就是枚舉的實(shí)例。
  3. red.ordinal() 方法返回該實(shí)例聲明的次序從0開始宪迟。
  4. 2個(gè)實(shí)例可用 == 比較
  5. Enum 實(shí)現(xiàn)了 Comparable<E>和 Serializable 可以使用comparableTo( )方法刊愚,可以序列化
  6. a. getDeclaringClass() 返回 Color.class 對(duì)象
  7. a.name和a.toString( )方法一樣。
  8. ? valuesOf(string ) 返回一個(gè)實(shí)例對(duì)象 Color b = Color.valueOf("BLUE");
  9. 根據(jù)class對(duì)象返回實(shí)例 Color b = Color.valueOf( Color.class, "BLUE" )

通過(guò)帶參構(gòu)造器為枚舉實(shí)例添加描述信息踩验。調(diào)用 getDes()就可以的到當(dāng)前對(duì)象的描述信息

調(diào)用 getDes( )方法就可以的到當(dāng)前對(duì)象的描述信息

public enum Color {
    RED("這是紅色"),
    BLUE("這是藍(lán)色"),
    YELLOW("這是黃色"),
    PURPLE("這是紫色");
    String des;
    Color( String s) {
        this.des = s;
    }
    public String getDes(){
        return des;
    }
}

重寫toString( )方法來(lái)為enum實(shí)例添加描述信息

public enum Color {
    RED,
    BLUE,
    YELLOW,
    PURPLE;

    @Override
    public String toString() {
        String id = name();
        return id + " is " + id.toLowerCase();
    }
}

通過(guò)name() 拿到當(dāng)前對(duì)象名字

enum的特殊方法

除了不能繼承enum類外鸥诽,enum和其普通類沒區(qū)別,可以添加字段箕憾,方法牡借,甚至是main 方法

  1. enum 實(shí)例也可以用在 switch語(yǔ)句中
  2. values()方法不在Enum中 它是由編譯器添加的static方法
  3. 編譯器還添加了一個(gè)valuesOf(String s)方法,這個(gè)只需要一個(gè)參數(shù)就可以的得到實(shí)例袭异,而Enum的需要2個(gè)
  4. 如果將enum向上轉(zhuǎn)型為Enum那么values 和 valuesOf 無(wú)法再使用
  5. 與values 方法有相同作用的就是Class對(duì)象的getEnumConstants()钠龙,如果class是枚舉類那么返回元素?cái)?shù)組,不是枚舉類返回null

使用接口組織枚舉

為了實(shí)現(xiàn)擴(kuò)展enum 或者將enum分類御铃,因?yàn)闊o(wú)法繼承所以靠擴(kuò)展子類無(wú)法實(shí)現(xiàn)碴里,可以利用接口來(lái)達(dá)到這些功能

public interface Food {
    enum Fruit implements Food{
        APPLE, BANANA, ORANGE;
    }
    enum Vegetables implements Food{
        TOMATO, POTATO, BEANS;
    }
    enum Drink implements Food{
        COFFEE, COCA, REDBULL;
    }
}


   public static void main(String[] args) {
        Food food = Food.Fruit.APPLE;
        food = Food.Drink.REDBULL;
        food = Food.Vegetables.BEANS;
    }

接口基礎(chǔ)上創(chuàng)建一個(gè)枚舉的枚舉,通過(guò)該enum控制其他enum上真,而不是不同的類型分別都要向上轉(zhuǎn)型為Food 咬腋,類多時(shí)分別向上轉(zhuǎn)型不如每個(gè)用一個(gè)enum控制方便

通過(guò)實(shí)例調(diào)用getValues方法就可以的到該實(shí)例的所有元素

public enum Course {
    FRUIT(Food.Fruit.class),
    DRINK(Food.Drink.class),
    VEGETABLES(Food.Vegetables.class);
    private Food[] values;
    Course(Class<? extends Food> kind) {
        this.values = kind.getEnumConstants();
    }
    public Food[] getValues() {
        return values;
    }
}

enum嵌套在另一個(gè)enum 重新組織1 2 代碼合二為一

public enum Course {
    FRUIT(Food.Fruit.class),
    DRINK(Food.Drink.class),
    VEGETABLES(Food.Vegetables.class);
    private Food[] values;

    Course(Class<? extends Food > kind) {
        this.values = kind.getEnumConstants();
    }

    interface Food {
        enum Fruit implements Food {
            APPLE, BANANA, ORANGE;
        }

        enum Vegetables implements Food {
            TOMATO, POTATO, BEANS;
        }

        enum Drink implements Food {
            COFFEE, COCA, REDBULL;
        }
    }

    public Food[] getValues() {
        return values;
    }
   
}

EnumSet

EnumSet (抽象類)一個(gè)用來(lái)存放enum 元素的Set,存取enum速度非常快睡互,性能非常高

  1. EnumSet 只能存放enum元素根竿,不能插入空元素

  2. 放入的元素位置和enum中保持一樣陵像,它處于排序狀態(tài),是一個(gè)有序Set

  3. Enum 是個(gè)抽象類且方法除了colon( )克隆一個(gè)EnumSet外都是靜態(tài)方法返回值都是EnumSet

EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); //創(chuàng)建一個(gè)空集
EnumSet<Color> enumSet2 = EnumSet.allOf(Color.class); //把集合中所有元素添加進(jìn)去
EnumSet<Color> enumSet3 = EnumSet.of(RED);//添加一個(gè)元素

EnumSet不止這幾個(gè)方法寇壳,對(duì)于of() 方法重載了6次醒颖,當(dāng)傳入2-5個(gè)參數(shù)調(diào)用相應(yīng)方法,傳入1個(gè)或者5個(gè)以上調(diào)用可變參數(shù)

EnumMap

特殊Map(類)壳炎,key必須是enum, 由于enum元素有限所以內(nèi)部只是由數(shù)組實(shí)現(xiàn)

  1. 這是一個(gè)有序map泞歉,保持enum的元素順序

  2. EnumMap<Color,Object> map = new EnumMap<Color, Object>(Color.class)

  3. 方法和其他Map一樣

實(shí)例對(duì)象添加方法

為每一個(gè)enum實(shí)例(相當(dāng)于常量)添加一個(gè)方法,讓他們有不同的行為

為每一個(gè)實(shí)例添加不同行為的方法

  1. 在enum中創(chuàng)建一個(gè)或者多個(gè)abstract 方法匿辩,因?yàn)槭莈num的實(shí)例所以就得實(shí)現(xiàn)這些方法
RED{
        @Override
        String getInfo() {
            return null;
        }

        @Override
        String getTime() {
            return null;
        }
    };
    abstract String getInfo();
    abstract String getTime();
  1. enum也可以有main方法作為enum執(zhí)行入口
  2. 常量添加方法后和有了類的行為腰耙,貌似和內(nèi)部類一樣,但他們有著不同行為撒汉,enum的常量不能作為方法參數(shù)類型沟优,因?yàn)樗麄儾皇穷悾皇莈num類型的static final 實(shí)例
  3. 由于enum的常量是 static final 的所以常量的方法不能訪問(wèn)外部類的非靜態(tài)方法

覆蓋常量相關(guān)的方法

  1. enum中所有非抽象方法每個(gè)實(shí)例都可以調(diào)
  2. 如果不需要每個(gè)實(shí)例都實(shí)現(xiàn)抽象類睬辐,那么就可以不用定義抽象類挠阁,每個(gè)實(shí)例各自實(shí)現(xiàn)方法,實(shí)現(xiàn)的方法可以覆蓋enum中的方法

使用enum職責(zé)鏈

  • 多種不同的方式解決問(wèn)題溯饵,然后把它們連接在一起侵俗,但一個(gè)請(qǐng)求到達(dá)時(shí)遍歷整個(gè)鏈,直到解決問(wèn)題
  • enum非常適合作為解決某一個(gè)問(wèn)題的職責(zé)鏈丰刊,請(qǐng)求到達(dá)時(shí)遍歷整個(gè)enum隘谣,直到解決問(wèn)題
import java.util.EnumSet;
import java.util.Random;

public enum COR {
    SOLUTION_ONE{
        @Override
        boolean Solve(int i) {
            if (i == 1){
                System.out.println(name()+" 解決問(wèn)題 " +i);
                return true;
            } return false;
        }
    },
    SOLUTION_TWO{
        @Override
        boolean Solve(int i) {
            if (i == 2){
                System.out.println(name()+" 解決問(wèn)題 " +i);
                return true;
            }return false;
        }
    },
    SOLUTION_THREE{
        @Override
        boolean Solve(int i) {
            if (i == 3){
                System.out.println(name()+" 解決問(wèn)題 " +i);
                return true;
            }return false;
        }
    },
    SOLUTION_FOUR{
        @Override
        boolean Solve(int i) {
            if (i == 4){
                System.out.println(name()+" 可以解決問(wèn)題 " +i);
                return true;
            }return false;
        }
    };

    abstract boolean Solve(int i);

    public static void main(String[] args) {
        Random random = new Random();
        EnumSet<COR> cors = EnumSet.allOf(COR.class);
        for (int i = 0; i < 6; i++) {
            int id = random.nextInt(4)+1;
            for (COR cor :cors) {
                if (cor.Solve(id)){
                    System.out.println(" 解決問(wèn)題 " +id);
                    break;
                }
            }
        }
    }

}

enum狀態(tài)機(jī)

  • 狀態(tài)機(jī)可以具有 有限個(gè) 狀態(tài),通常根據(jù)輸入啄巧,從一個(gè)狀態(tài)轉(zhuǎn)移到下一個(gè)狀態(tài)寻歧,也可以有瞬時(shí)狀態(tài),一但任務(wù)結(jié)束就立刻離開瞬時(shí)狀態(tài)

多路分發(fā)

  • 多種類型交互時(shí)有時(shí)并不能確定所有類型秩仆,如: NUM.complete(NUM) , NUM 是所有數(shù)字類型的超類码泛,a.complete(b) ,a b可能是同種類型也可能不是同一種類型
  • Java 動(dòng)態(tài)綁定只能處理一種類型,屬于單路分發(fā)(分派)澄耍,動(dòng)態(tài)綁定能將complete綁定到分路a噪珊。只有方法調(diào)用才會(huì)執(zhí)行動(dòng)態(tài)綁定

可以為每一個(gè)分發(fā)實(shí)現(xiàn)自己的動(dòng)態(tài)綁定

public enum Outcome { WIN, LOSE, DRAW } ///:~  
  
  
interface Item {  
    Outcome compete(Item it);  
  
    Outcome eval(Paper p);  
  
    Outcome eval(Scissors s);  
  
    Outcome eval(Rock r);  
}  
  
class Paper implements Item {  
    public Outcome compete(Item it) {  
        return it.eval(this);  
    }  
  
    public Outcome eval(Paper p) {  
        return DRAW;  
    }  
  
    public Outcome eval(Scissors s) {  
        return WIN;  
    }  
  
    public Outcome eval(Rock r) {  
        return LOSE;  
    }  
  
    public String toString() {  
        return "Paper";  
    }  
}  
  
class Scissors implements Item {  
    public Outcome compete(Item it) {  
        return it.eval(this);  
    }  
  
    public Outcome eval(Paper p) {  
        return LOSE;  
    }  
  
    public Outcome eval(Scissors s) {  
        return DRAW;  
    }  
  
    public Outcome eval(Rock r) {  
        return WIN;  
    }  
  
    public String toString() {  
        return "Scissors";  
    }  
}  
  
class Rock implements Item {  
    public Outcome compete(Item it) {  
        return it.eval(this);  
    }  
      
    public Outcome eval(Paper p) {  
        return WIN;  
    }  
  
    public Outcome eval(Scissors s) {  
        return LOSE;  
    }  
  
    public Outcome eval(Rock r) {  
        return DRAW;  
    }  
  
    public String toString() {  
        return "Rock";  
    }  
}  
  
public class RoShamBo1 {  
    static final int SIZE = 20;  
    private static Random rand = new Random(47);  
  
    public static Item newItem() {  
        switch (rand.nextInt(3)) {  
        default:  
        case 0:  
            return new Scissors();  
        case 1:  
            return new Paper();  
        case 2:  
            return new Rock();  
        }  
    }  
  
    public static void match(Item a, Item b) {  
        System.out.println(a + " vs. " + b + ": " + a.compete(b));  
    }  
  
    public static void main(String[] args) {  
        for (int i = 0; i < SIZE; i++)  
            match(newItem(), newItem());  
    }  
}

使用enum實(shí)現(xiàn)多路分發(fā)

  1. enum的實(shí)例不能作為類型參數(shù),不可以重載方法
  2. 可以使用enum構(gòu)造器初始化每個(gè)enum實(shí)例齐莲,并以一組結(jié)果作為參數(shù)如 ENUM_A( vsA_DRAW, vsB_LOSE, vsC_WIN ) 在比較方法中使用switch 判斷 返回 結(jié)果
package enums;

import static enums.OutCome.*;

public enum RoSham {
    PAPER(DRAW, LOSE, WIN),
    SCISSORS(WIN, DRAW, LOSE),
    ROCK(LOSE, WIN, DRAW);

    private OutCome vPAPER, vSCISSORS, vROCK;

    RoSham(OutCome paper, OutCome scissors, OutCome rock) {
        this.vPAPER = paper;
        this.vSCISSORS = scissors;
        this.vROCK = rock;
    }

    public OutCome complete(RoSham it) {
        switch (it) {
            default:
            case PAPER:
                return vPAPER;
            case SCISSORS:
                return vSCISSORS;
            case ROCK:
                return vROCK;
        }
    }

    public static void main(String[] args) {
        System.out.println(PAPER.complete(ROCK));
    }
}

PAPER.complete()時(shí)把PAPER構(gòu)造器中的結(jié)果與 OutCome 變量綁定痢站,根據(jù)對(duì)比的參數(shù)返回對(duì)比結(jié)果,因此實(shí)例構(gòu)造器中的參數(shù)位置非常重要

EnumMap實(shí)現(xiàn)真正的多路分發(fā)

package enums;

import java.util.EnumMap;

import static enums.OutCome.*;

public enum RoShamBo {
    PAPER, SCISSORS, ROCK;
    static EnumMap<RoShamBo, EnumMap<RoShamBo, OutCome>>
            table = new EnumMap<RoShamBo, EnumMap<RoShamBo, OutCome>>(RoShamBo.class);

    static {
        for (RoShamBo it : RoShamBo.values()) {

            table.put(it, new EnumMap<RoShamBo, OutCome>(RoShamBo.class));
        }

        initRow(PAPER, DRAW, LOSE, WIN);
        initRow(SCISSORS, WIN, DRAW, LOSE);
        initRow(ROCK, LOSE, WIN, DRAW);

    }

    static void initRow(RoShamBo it, OutCome vPAPER, OutCome vSCISSORS, OutCome vROCK) {
        EnumMap<RoShamBo, OutCome> row = RoShamBo.table.get(it);
        row.put(RoShamBo.PAPER, vPAPER);
        row.put(RoShamBo.SCISSORS, vSCISSORS);
        row.put(RoShamBo.ROCK, vROCK);
    }

    public OutCome complete(RoShamBo it) {
        return table.get(this).get(it);
    }

    public static void main(String[] args) {
        System.out.println(ROCK.complete(SCISSORS));
    }

}

complete方法實(shí)現(xiàn)了2次分發(fā)

使用二維數(shù)組

  • 簡(jiǎn)單选酗,速度快阵难,代碼易懂,但是組數(shù)比較大時(shí)尺寸容易錯(cuò)
private static OutCome[][] tables = {
        {DRAW, LOSE, WIN},
        {WIN, DRAW, LOSE},
        {LOSE, WIN, DRAW},
    };

    public OutCome completes (RoShamBo other) {
        return tables[this.ordinal()][other.ordinal()];
    }

知識(shí)點(diǎn)

可以靜態(tài)導(dǎo)入枚舉類 直接使用枚舉實(shí)例 import static ......Color.* 最好使用靜態(tài)導(dǎo)入省去寫enum類

參考文章

《Java編程思想》 -- 筆記

《Java編程思想》筆記 第十九章 枚舉類型

淺談在Java開發(fā)中的枚舉的作用和用法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末星掰,一起剝皮案震驚了整個(gè)濱河市多望,隨后出現(xiàn)的幾起案子嫩舟,更是在濱河造成了極大的恐慌氢烘,老刑警劉巖怀偷,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異播玖,居然都是意外死亡椎工,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門蜀踏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)维蒙,“玉大人,你說(shuō)我怎么就攤上這事果覆÷” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵局待,是天一觀的道長(zhǎng)斑响。 經(jīng)常有香客問(wèn)我,道長(zhǎng)钳榨,這世上最難降的妖魔是什么舰罚? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮薛耻,結(jié)果婚禮上营罢,老公的妹妹穿的比我還像新娘。我一直安慰自己饼齿,他們只是感情好饲漾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缕溉,像睡著了一般考传。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上倒淫,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天伙菊,我揣著相機(jī)與錄音,去河邊找鬼敌土。 笑死镜硕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的返干。 我是一名探鬼主播兴枯,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼矩欠!你這毒婦竟也來(lái)了财剖?” 一聲冷哼從身側(cè)響起悠夯,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎躺坟,沒想到半個(gè)月后沦补,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咪橙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年夕膀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片美侦。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡产舞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出菠剩,到底是詐尸還是另有隱情易猫,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布具壮,位于F島的核電站准颓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嘴办。R本人自食惡果不足惜瞬场,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涧郊。 院中可真熱鬧贯被,春花似錦、人聲如沸妆艘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)批旺。三九已至幌陕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汽煮,已是汗流浹背搏熄。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暇赤,地道東北人心例。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鞋囊,于是被迫代替她去往敵國(guó)和親止后。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容