Java 高級(jí):反射知識(shí)總結(jié)

一宪肖、背景


要理解反射永淌,首先要知道它產(chǎn)生的背景。

在 Java 中见秤,正常情況下我們只需要 new 某個(gè)類來(lái)使用就行了砂竖,但是如果想在運(yùn)行時(shí)靈活創(chuàng)建某個(gè)類怎么辦?想要使用某個(gè)類但是并沒(méi)有被 JVM 加載怎么辦鹃答?

答案就是利用 反射乎澄,這個(gè)機(jī)制可以幫助我們?cè)谶\(yùn)行期需要的時(shí)候去加載創(chuàng)建某個(gè)類,從而使用該類的方法测摔。

這里引用 知乎Kira 的回答可能更容易理解:

假如你寫(xiě)了一段代碼:Object o=new Object();運(yùn)行了起來(lái)三圆!
首先JVM會(huì)啟動(dòng),你的代碼會(huì)編譯成一個(gè).class文件避咆,然后被類加載器加載進(jìn)jvm的內(nèi)存中舟肉,你的類Object加載到方法區(qū)中,創(chuàng)建了Object類的class對(duì)象到堆中查库,注意這個(gè)不是new出來(lái)的對(duì)象路媚,而是類的類型對(duì)象,每個(gè)類只有一個(gè)class對(duì)象樊销,作為方法區(qū)類的數(shù)據(jù)結(jié)構(gòu)的接口整慎。
jvm創(chuàng)建對(duì)象前,會(huì)先檢查類是否加載围苫,尋找類對(duì)應(yīng)的class對(duì)象裤园,若加載好,則為你的對(duì)象分配內(nèi)存剂府,初始化也就是代碼:new Object()拧揽。
上面的流程就是你自己寫(xiě)好的代碼扔給jvm去跑,跑完就over了,jvm關(guān)閉淤袜,你的程序也停止了痒谴。

相當(dāng)于這些代碼都是寫(xiě) "死" 的,但是在運(yùn)行時(shí)要使用則需要利用反射通過(guò)包名靈活地加載某些類铡羡。

二积蔚、反射的組件


實(shí)現(xiàn)反射的一些主要類都處于 java.lang 包下:

  • Class:代表一個(gè)類;
  • Field:代表類的成員變量(屬性)烦周;
  • Method:代表類的方法尽爆;
  • Constructor:代表構(gòu)造器(構(gòu)造函數(shù)、構(gòu)造方法)读慎;
  • Array:提供動(dòng)態(tài)創(chuàng)建數(shù)組漱贱,以及訪問(wèn)數(shù)組元素的方法;
  • Package:存放路徑贪壳,包名饱亿;

接下來(lái)看一下怎么獲取這些組件蚜退。

類對(duì)象 Class

  • 通過(guò)類型獲热蜓ァ;
Class c = String.class;
  • 通過(guò)對(duì)象獲茸曜ⅰ:
Class c = o.getClass();
名稱 作用
getName() 返回String形式的該類的名稱蚂且。
newInstance() 根據(jù)某個(gè)Class對(duì)象產(chǎn)生其對(duì)應(yīng)類的實(shí)例,它調(diào)用的是此類的默認(rèn)構(gòu)造方法(沒(méi)有默認(rèn)無(wú)參構(gòu)造器會(huì)報(bào)錯(cuò))
getClassLoader() 返回該Class對(duì)象對(duì)應(yīng)的類的類加載器幅恋。
getSuperClass() 返回某子類所對(duì)應(yīng)的直接父類所對(duì)應(yīng)的Class對(duì)象
isArray() 判定此Class對(duì)象所對(duì)應(yīng)的是否是一個(gè)數(shù)組對(duì)象
getComponentType() 如果當(dāng)前類表示一個(gè)數(shù)組杏死,則返回表示該數(shù)組組件的 Class 對(duì)象,否則返回 null捆交。
getConstructor(Class[]) 返回當(dāng)前 Class 對(duì)象表示的類的指定的公有構(gòu)造子對(duì)象淑翼。
getConstructors() 返回當(dāng)前 Class 對(duì)象表示的類的所有公有構(gòu)造子對(duì)象數(shù)組。
getDeclaredConstructor(Class[]) 返回當(dāng)前 Class 對(duì)象表示的類的指定已說(shuō)明的一個(gè)構(gòu)造子對(duì)象品追。
getDeclaredConstructors() 返回當(dāng)前 Class 對(duì)象表示的類的所有已說(shuō)明的構(gòu)造子對(duì)象數(shù)組玄括。
getDeclaredField(String) 返回當(dāng)前 Class 對(duì)象表示的類或接口的指定已說(shuō)明的一個(gè)域?qū)ο蟆?/td>
getDeclaredFields() 返回當(dāng)前 Class 對(duì)象表示的類或接口的所有已說(shuō)明的域?qū)ο髷?shù)組。
getDeclaredMethod(String, Class[]) 返回當(dāng)前 Class 對(duì)象表示的類或接口的指定已說(shuō)明的一個(gè)方法對(duì)象肉瓦。
getDeclaredMethods() 返回 Class 對(duì)象表示的類或接口的所有已說(shuō)明的方法數(shù)組遭京。
getField(String) 返回當(dāng)前 Class 對(duì)象表示的類或接口的指定的公有成員域?qū)ο蟆?/td>
getFields() 返回當(dāng)前 Class 對(duì)象表示的類或接口的所有可訪問(wèn)的公有域?qū)ο髷?shù)組。
getInterfaces() 返回當(dāng)前對(duì)象表示的類或接口實(shí)現(xiàn)的接口泞莉。
getMethod(String, Class[]) 返回當(dāng)前 Class 對(duì)象表示的類或接口的指定的公有成員方法對(duì)象哪雕。
getMethods() 返回當(dāng)前 Class 對(duì)象表示的類或接口的所有公有成員方法對(duì)象數(shù)組,包括已聲明的和從父類繼承的方法鲫趁。
isInstance(Object) 此方法是 Java 語(yǔ)言 instanceof 操作的動(dòng)態(tài)等價(jià)方法斯嚎。
isInterface() 判定指定的 Class 對(duì)象是否表示一個(gè)接口類型
isPrimitive() 判定指定的 Class 對(duì)象是否表示一個(gè) Java 的基類型。
newInstance() 創(chuàng)建類的新實(shí)例

構(gòu)造器 Constructor

首先使用 Class 對(duì)象獲取 Constructor

  • getConstructors()
  • getConstructor(Class<?>…parameterTypes)
  • getDeclaredConstructors()
  • getDeclaredConstructor(Class<?>...parameterTypes)

然后就可以使用 Constructor 的下列方法:

名稱 作用
isVarArgs() 查看該構(gòu)造方法是否允許帶可變數(shù)量的參數(shù),如果允許孝扛,返回 true列吼,否則返回false
getParameterTypes() 按照聲明順序以 Class 數(shù)組的形式獲取該構(gòu)造方法各個(gè)參數(shù)的類型
getExceptionTypes() 以 Class 數(shù)組的形式獲取該構(gòu)造方法可能拋出的異常類型
newInstance(Object … initargs) 通過(guò)該構(gòu)造方法利用指定參數(shù)創(chuàng)建一個(gè)該類型的對(duì)象,如果未設(shè)置參數(shù)則表示采用默認(rèn)無(wú)參的構(gòu)造方法
setAccessiable(boolean flag) 如果該構(gòu)造方法的權(quán)限為 private苦始,默認(rèn)為不允許通過(guò)反射利用 netlnstance()方法創(chuàng)建對(duì)象寞钥。如果先執(zhí)行該方法,并將入口參數(shù)設(shè)置為 true陌选,則允許創(chuàng)建對(duì)象
getModifiers() 獲得可以解析出該構(gòu)造方法所采用修飾符的整數(shù)

Modifier 用來(lái)獲取修飾符信息理郑,比如 isStatic(int mod) 返回是否靜態(tài)、isPublic(int mod) 是否公共咨油。不只是構(gòu)造器類型含有此方法您炉,函數(shù)、屬性都有此方法役电。

方法 Method

名稱 作用
getName() 獲取該方法的名稱
getParameterType() 按照聲明順序以 Class 數(shù)組的形式返回該方法各個(gè)參數(shù)的類型
getReturnType() 以 Class 對(duì)象的形式獲得該方法的返回值類型
getExceptionTypes() 以 Class 數(shù)組的形式獲得該方法可能拋出的異常類型
invoke(Object obj,Object...args) 利用 args 參數(shù)執(zhí)行指定對(duì)象 obj 中的該方法赚爵,返回值為 Object 類型
isVarArgs() 查看該方法是否允許帶有可變數(shù)量的參數(shù),如果允許返回 true法瑟,否則返回 false
getModifiers() 獲得可以解析出該方法所采用修飾符的整數(shù)

屬性冀膝、字段 Field

名稱 作用
getName() 獲得該成員變量的名稱
getType() 獲取表示該成員變量的 Class 對(duì)象
get(Object obj) 獲得指定對(duì)象 obj 中成員變量的值,返回值為 Object 類型
set(Object obj, Object value) 將指定對(duì)象 obj 中成員變量的值設(shè)置為 value
getlnt(0bject obj) 獲得指定對(duì)象 obj 中成員類型為 int 的成員變量的值
setlnt(0bject obj, int i) 將指定對(duì)象 obj 中成員變量的值設(shè)置為 i
setFloat(Object obj, float f) 將指定對(duì)象 obj 中成員變量的值設(shè)置為 f
getBoolean(Object obj) 獲得指定對(duì)象 obj 中成員類型為 boolean 的成員變量的值
setBoolean(Object obj, boolean b) 將指定對(duì)象 obj 中成員變量的值設(shè)置為 b
getFloat(Object obj) 獲得指定對(duì)象 obj 中成員類型為 float 的成員變量的值
setAccessible(boolean flag) 此方法可以設(shè)置是否忽略權(quán)限直接訪問(wèn) private 等私有權(quán)限的成員變量
getModifiers() 獲得可以解析出該方法所采用修飾符的整數(shù)

數(shù)組相關(guān) Array

名稱 作用
newInstance(Class<?> componentType, int length) 創(chuàng)建一個(gè) componentType 類型的數(shù)組霎挟,設(shè)定長(zhǎng)度
getLength(Object array) 獲取數(shù)組長(zhǎng)度
get(Object array, int index) 獲取數(shù)組指定下標(biāo)位置的數(shù)據(jù)
set(Object array, int index, Object value) 設(shè)置數(shù)組指定下標(biāo)位置的數(shù)據(jù)

三窝剖、使用


獲取組件

接下來(lái)寫(xiě)一個(gè)簡(jiǎn)單的小例子來(lái)看下反射的使用,首先準(zhǔn)備一個(gè) Student 類:

package com.sky.test.ref;

public class Student {

    private int privateAge;
    public int publicAge;

    public void publicStudy(){
    }

    private void privateStudy(){
    }
}

很簡(jiǎn)單的類酥夭,擁有一個(gè)私有赐纱、一個(gè)公共屬性,一個(gè)私有熬北、一個(gè)公共方法疙描,接下來(lái)使用反射獲取這些信息。

public static void main(String[] args) {

    try {
        // 根據(jù)包名找到類型
        Class<?> classType = Class.forName("com.sky.test.ref.Student");

        // 獲取所有屬性
        Field[] fields = classType.getFields();
        Field[] fieldsD = classType.getDeclaredFields();
        for (Field f : fields) {
            System.out.println("getFields 獲取到的屬性:" + f.getName());
            // getFields 獲取到的屬性:publicAge
        }

        for (Field f : fieldsD) {
            System.out.println("getDeclaredFields 獲取到的屬性:" + f.getName());
            // getDeclaredFields 獲取到的屬性:privateAge
            // getDeclaredFields 獲取到的屬性:publicAge
        }

        // 獲取該類的所有方法
        Method[] methods = classType.getMethods();
        Method[] methodsD = classType.getDeclaredMethods();
        for (Method m : methods) {
            System.out.println("getMethods 獲取到的方法:" + m.getName());
            // getMethods 獲取到的方法:publicStudy
            // getMethods 獲取到的方法:wait
            // getMethods 獲取到的方法:wait
            // getMethods 獲取到的方法:wait
            // getMethods 獲取到的方法:equals
            // getMethods 獲取到的方法:toString
            // getMethods 獲取到的方法:hashCode
            // getMethods 獲取到的方法:getClass
            // getMethods 獲取到的方法:notify
            // getMethods 獲取到的方法:notifyAll
        }

        for (Method m : methodsD) {
            System.out.println("getDeclaredMethods 獲取到的方法:" + m.getName());
            // getDeclaredMethods 獲取到的方法:publicStudy
            // getDeclaredMethods 獲取到的方法:privateStudy
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}
  • Class.forName() 方法傳入包名讶隐,以找到想要使用的類起胰,找不到會(huì)拋 ClassNotFoundException 異常;
  • ClassgetFields() 方法:獲取所有 公共的(public) 的屬性整份,包含父類的 public 屬性(但不包含父類非 public 屬性)待错;
  • ClassgetDeclaredFields() 方法:獲取本類所有的屬性,但不包含父類的屬性烈评;
  • ClassgetMethods() 方法:獲取所有 公共的(public) 的方法火俄,包含父類的 public 方法(但不包含父類非 public 方法);
  • ClassgettDeclaredMethods() 方法:獲取本類所有的方法讲冠,但不包含父類的方法瓜客;

簡(jiǎn)單使用

已經(jīng)成功獲取到這些方法和屬性了,接下來(lái)就是使用通過(guò)反射獲取到的屬性和方法了。但是首先要做的是能把修改的信息展示出來(lái)谱仪,把 Student 類簡(jiǎn)單修改下:

public class Student extends SuperStudent {

    private int privateAge;
    public int publicAge;

    public void publicStudy(int hour) {
        System.out.println("設(shè)置年齡為" + publicAge);
        System.out.println("學(xué)習(xí)了" + hour + "小時(shí)");
    }

    private void privateStudy() {
    }
}

只是給 publicStudy() 方法增加了 int 類型的參數(shù)玻熙,并打印了兩個(gè)字段:publicAge、hour疯攒。接下來(lái)就可以使用反射來(lái)修改里面的信息了嗦随。

public static void main(String[] args) {

    try {
        // 1. 根據(jù)包名找到類型
        Class<?> classType = Class.forName("com.sky.test.ref.Student");
        // 創(chuàng)建實(shí)例,修改該對(duì)象的信息
        Object o = classType.newInstance();
        // 2. 獲取 年齡 字段
        Field field = classType.getDeclaredField("publicAge");
        // 設(shè)置年齡 publicAge 屬性:第一個(gè)參數(shù)為要修改的對(duì)象敬尺,第二個(gè)參數(shù)為數(shù)值
        field.set(o, 1);
        // 3. 獲取 publicStudy 方法枚尼,第二個(gè)參數(shù)傳入?yún)?shù)類型
        Method method = classType.getDeclaredMethod("publicStudy", int.class);
        // 調(diào)用 publicStudy 方法
        method.invoke(o, 3);
        
    } catch (ClassNotFoundException
            | NoSuchFieldException
            | NoSuchMethodException | IllegalAccessException
            | InstantiationException | InvocationTargetException
            e) {
        e.printStackTrace();
    }

}
  1. 首先要做的是找到該類型,并創(chuàng)建該類型的對(duì)象砂吞。修改數(shù)據(jù)首先得有對(duì)象吧署恍,然后內(nèi)存空間有它的地方吧,不然修改啥蜻直。
  2. 然后就是獲取字段了盯质,我們要做的是修改年齡 publicAge 字段:獲取該字段的 Field 對(duì)象,使用 set() 傳入 對(duì)象 和要修改的值概而,這樣就 ok 了呼巷。
  3. 類似的方法獲取 publicStudy() 方法,調(diào)用 invoke() 方法傳參激活打印到腥。特別注意: 第二個(gè)參數(shù)是當(dāng)前方法的參數(shù)類型朵逝,如果傳的不對(duì)直接給你報(bào) NoSuchMethodException蔚袍。而且注意 int.classInteger.class 竟然不是一個(gè)東西乡范,傳 Integer 還是會(huì)報(bào)錯(cuò)...

這樣就完成了普通的使用。

特別注意:權(quán)限問(wèn)題

反射使用引入了權(quán)限機(jī)制啤咽,私有的屬性已經(jīng)方法直接反射調(diào)用的話會(huì)拋出異常晋辆。

Field fieldPrivate = classType.getDeclaredField("privateAge");
fieldPrivate.set(o,2); // 會(huì)拋出 java.lang.IllegalAccessException 異常

如果想要使用的話,需要設(shè)置屬性或方法等的訪問(wèn)權(quán)限:

Field fieldPrivate = classType.getDeclaredField("privateAge");
fieldPrivate.setAccessible(true);
fieldPrivate.set(o,2);

注解使用

注解一般也是利用反射來(lái)使用的宇整,大概過(guò)程就是利用反射獲取 Class 類型上面的注解瓶佳,然后執(zhí)行相應(yīng)邏輯。

之前寫(xiě)過(guò)一篇文章有記錄鳞青,在此不再贅述霸饲。

談?wù)勀銓?duì)注解的理解 第三節(jié)

遠(yuǎn)程方法運(yùn)用反射

摘自 Java在遠(yuǎn)程方法調(diào)用中運(yùn)用反射機(jī)制

  • 服務(wù)端:HelloService
  • 客戶端:SimpleClient
  • 通信信息:Call

客戶端生成 Call 對(duì)象,指定要調(diào)用的類臂拓、對(duì)象以及方法參數(shù)等信息厚脉,通過(guò)流的形式發(fā)生給服務(wù)端。

public class Call implements Serializable {
    private static final long serialVersionUID = 6659953547331194808L;
    private String className; // 表示類名或接口名
    private String methodName; // 表示方法名
    private Class[] paramTypes; // 表示方法參數(shù)類型
    private Object[] params; // 表示方法參數(shù)值
    // 表示方法的執(zhí)行結(jié)果
    // 如果方法正常執(zhí)行胶惰,則result為方法返回值傻工,如果方法拋出異常,那么result為該異常。
    private Object result;
    ...
}

服務(wù)端處理過(guò)將結(jié)果再以流的形式返回給客戶端中捆。

遠(yuǎn)程反射

反射操作數(shù)組

需求: 創(chuàng)建一個(gè)數(shù)組鸯匹,通過(guò)反射獲取數(shù)組的類型,然后創(chuàng)建一個(gè)新長(zhǎng)度的新數(shù)組泄伪,拷貝舊數(shù)組的內(nèi)容殴蓬。

為了看出效果,首先為 Student 類增加一個(gè)靜態(tài)的創(chuàng)建方法:

public class Student extends SuperStudent {
    public int publicAge;
    ...
    public static Student newInstance(){
        Student student = new Student();
        student.publicAge = 8;
        return student;
    }
}

使用此方法創(chuàng)建實(shí)例蟋滴,給內(nèi)部的年齡字段一個(gè)初始值 8科雳。接下來(lái)就創(chuàng)建一個(gè) Student 的數(shù)組,并利用反射進(jìn)行創(chuàng)建和復(fù)制脓杉。

public static void main(String[] args) {

    // 1. 創(chuàng)建數(shù)組糟秘,里面存放一個(gè) Student 對(duì)象
    Student[] students = new Student[]{Student.newInstance()};
    // 2. 獲取元素類型
    Class<?> classType = students.getClass().getComponentType();

    // 3. 創(chuàng)建新數(shù)組
    Object[] objects = (Object[]) Array.newInstance(classType, Array.getLength(students));
    // 4. 進(jìn)行 copy:原數(shù)組,拷貝起始球散,新數(shù)組尿赚,拷貝起始,拷貝長(zhǎng)度
    System.arraycopy(students, 0, objects, 0, Array.getLength(students));

    // 5. 從新數(shù)組獲取第一個(gè)元素
    Student s = (Student)Array.get(objects, 0);
    System.out.println("拷貝完成蕉堰,第一個(gè)數(shù)據(jù)年齡: " + s.publicAge);
    // 拷貝完成凌净,第一個(gè)數(shù)據(jù)年齡: 8
}

需要注意的是一些方法的使用:

  • getClass()getComponentType() 的區(qū)別:
    getClass()用于獲取對(duì)象的類型,比如這里獲取數(shù)組的是 Student[] 類型屋讶;
    getComponentType() 獲取數(shù)組元素類型冰寻,比如這里獲取到的是 Student 類型。

  • Array.newInstance() 可以幫助我們動(dòng)態(tài)創(chuàng)建數(shù)組皿渗,可以從別的地方傳遞來(lái)類型和長(zhǎng)度斩芭,即可完成創(chuàng)建。

反射操作泛型

知識(shí)儲(chǔ)備:

  • Type:所有類型的公共父接口乐疆,Class 就是 Type 的子類之一划乖,以下是該接口的子類型:
    • ParameterizedType:參數(shù)化類型,可以理解為泛型挤土;
    • TypeVariable:類型變量琴庵,也就是平時(shí)定義的 T t、K k 等類似的變量仰美;
    • GenericArrayType:泛型數(shù)組類型迷殿,T[] 這種類型;
    • WildcardType:通配符類型咖杂,<?>, <? Extends String> 這種庆寺。

小栗子:

依舊是使用上面的 Student 類,給它增加一個(gè)包含泛型的方法:

public void setStudents(List<Student> list){
}

接下來(lái)就是獲取泛型:

public static void main(String[] args) {
    try {
        Method method = Student.class.getMethod("setStudents", List.class);
        // 獲取方法參數(shù)類型
        Type[] t = method.getGenericParameterTypes();

        for (Type type : t) {
            System.out.println("參數(shù)類型:" + type);// 泛型類型:java.util.List<com.sky.test.ref.Student>
            if (type instanceof ParameterizedType) {
                Type[] real = ((ParameterizedType) type).getActualTypeArguments();
                for (Type genericType : real) {
                    System.out.println("泛型類型:" + genericType);
                    // 泛型類型:class com.sky.test.ref.Student
                }
            }
        }

    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
}

這只是利用反射獲取泛型的一個(gè)很小的例子翰苫,可以使用不同的方法獲取 接口止邮、類等的參數(shù)这橙、返回值中的泛型。

說(shuō)起來(lái)為什么會(huì)把泛型擦除掉导披,是因?yàn)榉盒捅緛?lái)不是 Java 中的東西(可能是抄來(lái)的)屈扎。如果要把泛型加入字節(jié)碼,就需要修改字節(jié)碼指令集撩匕。我們都知道新增簡(jiǎn)單修改難鹰晨,這字節(jié)碼指令用了多少年了,要改基本不肯能了止毕。

所以把泛型擦除之后呢模蜡,又需要一些類型來(lái)表示到底是哪種泛型,于是就有了上面那些 Type 的子接口扁凛。

四忍疾、反射影響性能

這里引用文章 大家都說(shuō) Java 反射效率低,你知道原因在哪里么 的結(jié)論:

  1. Method#invoke 方法會(huì)對(duì)參數(shù)做封裝和解封操作
  2. 需要檢查方法可見(jiàn)性
  3. 需要校驗(yàn)參數(shù)
  4. 反射方法難以內(nèi)聯(lián)
  5. JIT 無(wú)法優(yōu)化

具體可以參考該文章谨朝,自此本文結(jié)束卤妒。

參考:

Java反射機(jī)制
Java 反射操作數(shù)組

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市字币,隨后出現(xiàn)的幾起案子则披,更是在濱河造成了極大的恐慌,老刑警劉巖洗出,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件士复,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡翩活,警方通過(guò)查閱死者的電腦和手機(jī)阱洪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)隅茎,“玉大人澄峰,你說(shuō)我怎么就攤上這事嫉沽”傧” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵绸硕,是天一觀的道長(zhǎng)堂竟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)玻佩,這世上最難降的妖魔是什么出嘹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮咬崔,結(jié)果婚禮上税稼,老公的妹妹穿的比我還像新娘烦秩。我一直安慰自己,他們只是感情好郎仆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布只祠。 她就那樣靜靜地躺著,像睡著了一般扰肌。 火紅的嫁衣襯著肌膚如雪抛寝。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天曙旭,我揣著相機(jī)與錄音盗舰,去河邊找鬼。 笑死桂躏,一個(gè)胖子當(dāng)著我的面吹牛钻趋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剂习,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼爷绘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了进倍?” 一聲冷哼從身側(cè)響起土至,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎猾昆,沒(méi)想到半個(gè)月后陶因,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡垂蜗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年楷扬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贴见。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烘苹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出片部,到底是詐尸還是另有隱情镣衡,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布档悠,位于F島的核電站廊鸥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辖所。R本人自食惡果不足惜惰说,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缘回。 院中可真熱鬧吆视,春花似錦典挑、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至丰滑,卻和暖如春顾犹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背褒墨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工炫刷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郁妈。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓浑玛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親噩咪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子顾彰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345