Java中的反射

反射

今天我來分享下, 我關(guān)于Java中反射的理解标沪。如果做過iOS開發(fā)的同學(xué)應(yīng)該很清楚iOS里Runtime的黑魔法, 而Java中的反射其實(shí)就是iOS中的Runtime.

什么是反射

反射是一種專門為靜態(tài)語言提供的技術(shù),用于在程序運(yùn)行時(shí)(Runtime)動(dòng)態(tài)的修改程序的結(jié)構(gòu),改變程序的行為.

Java為什么要引入反射

Java也是靜態(tài)語言.為了讓Java語言也能夠在運(yùn)行時(shí)修改類或者對(duì)象狀態(tài)和改變類或?qū)ο?/strong>的行為因此引入了反射機(jī)制.

靜態(tài)語言中,使用一個(gè)變量時(shí)绎谦,必須知道它的類型.在Java中兼都,變量的類型信息在編譯時(shí)都保存到了class文件中,這樣在運(yùn)行時(shí)才能保證準(zhǔn)確無誤.換句話說,程序在運(yùn)行時(shí)的行為都是固定的.如果想在運(yùn)行時(shí)改變,就需要反射這東西了.舉個(gè)例子:

在Spring中,有這樣的java bean配置:

<bean id="someID" class="com.sweetcs.AppleBean">
    <property name="someField" value="someValue" />
</bean>

Spring在處理這個(gè)bean標(biāo)簽時(shí),發(fā)現(xiàn)class屬性指定的是com.sweetcs.AppleBean這個(gè)類,就會(huì)調(diào)用Class.forName(String)來實(shí)例化這個(gè)類,再通過反射,可以取到someField屬性的值了.
如果我們想改變這個(gè)程序運(yùn)行時(shí)的信息,我們這里直接修改bean,property的屬性即可,無需重新編譯.

動(dòng)態(tài)語言中,使用變量不需要聲明類型后控,因而不需要這反射這種機(jī)制
比如在javascript中空镜,我們知道有個(gè)變量applebean浩淘,不管applebean有沒有sell()屬性,我們都可以這么寫:applebean.sell()
因?yàn)闆]有類型檢查吴攒,這里這么寫是允許的馋袜。至于在運(yùn)行時(shí)報(bào)不報(bào)錯(cuò),就要看運(yùn)行時(shí)applebean的真正值了舶斧。

一點(diǎn)思考

一欣鳖、反射是可在運(yùn)行期間確定對(duì)象的類型, 多態(tài)也是在運(yùn)行期間才確定類型, 那么多態(tài)的實(shí)現(xiàn)是否和反射有關(guān)?

  • 多態(tài)的技術(shù)上的實(shí)現(xiàn)是方法后期的動(dòng)態(tài)綁定, 即在運(yùn)行時(shí)才決定方法應(yīng)該綁定到那塊內(nèi)存中(該內(nèi)存即對(duì)應(yīng)相應(yīng)的對(duì)象)。
  • 反射技術(shù)上的實(shí)現(xiàn)是基礎(chǔ)是Java中的方法區(qū)的class,有的語言把它們稱為類對(duì)象.Java中的類都是有類對(duì)象創(chuàng)建的茴厉,我們可以通過類對(duì)象來管理我們創(chuàng)建的所有對(duì)象.
  • 說一說多態(tài)的實(shí)現(xiàn)本質(zhì)上和反射并沒有關(guān)系.

二泽台、為什么Java也能夠?qū)崿F(xiàn)反射,加入我們在編譯期間就確定了真實(shí)對(duì)象類型還能使用反射嗎?

  • Java在自建立以來就有反射技術(shù), 其反射技術(shù)和多態(tài)主要基于JVM在運(yùn)行時(shí)才動(dòng)態(tài)加載類或調(diào)用方法/訪問屬性的機(jī)制.該機(jī)制不需要事先(寫代碼的時(shí)候或編譯期)知道真實(shí)的運(yùn)行對(duì)象是誰.
  • 而反射是基于Class對(duì)象,我們每編寫的一個(gè)類,都會(huì)被編譯成字節(jié)碼文件,將類信息存儲(chǔ)在這個(gè)字節(jié)碼文件中,該文件即Class對(duì)象,在我們使用到這個(gè)Class的靜態(tài)成員變量或者成員時(shí)它就會(huì)加載進(jìn)JVM.
  • 多態(tài)主要是基于方法的動(dòng)態(tài)綁定,前提是JVM在運(yùn)行時(shí)才確定對(duì)象的真實(shí)類型,這時(shí)候才去綁定方法到真實(shí)的對(duì)象上.

反射機(jī)制的作用

我們先了解下反射究竟能做哪些事情, 可以分為以下四類.

  • 在運(yùn)行期間可以動(dòng)態(tài)的創(chuàng)建任意類型的對(duì)象
  • 在運(yùn)行期間可以獲取任意的類型的任意信息
  • 在運(yùn)行期間可以獲取某個(gè)對(duì)象某個(gè)屬性的值或設(shè)置某個(gè)屬性的值
  • 在運(yùn)行期間可以調(diào)用某個(gè)對(duì)象的任意方法

Class對(duì)象

要學(xué)習(xí)反射, 首先要學(xué)習(xí)Class對(duì)象,Class對(duì)象表示的是 我們類的類信息(我們編寫的類,).
比如創(chuàng)建一個(gè)Shapes類,那么,JVM就會(huì)創(chuàng)建一個(gè)Shapes對(duì)應(yīng)Class類的Class對(duì)象,該Class對(duì)象保存了Shapes類相關(guān)的類型信息.
實(shí)際上在Java中每個(gè)類都有一個(gè)Class對(duì)象,每當(dāng)我們編寫并且編譯一個(gè)新創(chuàng)建的類就會(huì)產(chǎn)生一個(gè)對(duì)應(yīng)Class對(duì)象并且這個(gè)Class對(duì)象會(huì)被保存在同名.class文件里(編譯后的字節(jié)碼文件保存的就是Class對(duì)象),那為什么需要這樣一個(gè)Class對(duì)象呢?是這樣的,當(dāng)我們new一個(gè)新對(duì)象或者引用靜態(tài)成員變量時(shí),Java虛擬機(jī)(JVM)中的類加載器子系統(tǒng)會(huì)將對(duì)應(yīng)Class對(duì)象加載到JVM中,然后JVM再根據(jù)這個(gè)類型信息相關(guān)的Class對(duì)象創(chuàng)建我們需要實(shí)例對(duì)象或者提供靜態(tài)變量的引用值.

獲取Class對(duì)象

類名.class

這種類型表明編譯期間就能確定類型。僅限于編譯期間這個(gè)類型是已知的矾缓。

@Test
public void test1(){
    Class c1 = int[].class;
    Class c2 = int[].class;
    System.out.println(c1 == c2);

    Class c3 = int[][].class;
    System.out.println(c1 == c3);

    Class c4 = byte[].class;
    System.out.println(c1 == c4);
}

對(duì)象.getClass()

獲取某個(gè)對(duì)象的運(yùn)行時(shí)類型

@Test
public void test2(){
    Object obj = new TestClass();
    Class class1 = obj.getClass();
    System.out.println(class1);
}

Class.forName(全限定類名)

使用properties配置文件, 動(dòng)態(tài)配置運(yùn)行時(shí)要?jiǎng)?chuàng)建的類.

@Test
public void test3() throws Exception{
    Properties pro = new Properties();
    //文件在src下怀酷,最終在bin等類路徑(.class文件)下,可以用ClassLoader加載這個(gè)文件
    //文件在src外面嗜闻,只能使用FileInputStream來加載
    pro.load(new FileInputStream("type.properties"));
    String name = pro.getProperty("typename");

    //這句代碼可能會(huì)發(fā)生:ClassNotFoundException蜕依,類型找不到異常
    Class clazz = Class.forName(name);
    System.out.println(clazz);
}

類加載器.loadClass(全限定類名)

@Test
public void test4()throws Exception{
    Properties pro = new Properties();
    //文件在src下,最終在bin等類路徑(.class文件)下琉雳,可以用ClassLoader加載這個(gè)文件
    //文件在src外面样眠,只能使用FileInputStream來加載
    pro.load(new FileInputStream("type.properties"));
    String name = pro.getProperty("typename");

    //獲取系統(tǒng)類加載器對(duì)象
    ClassLoader c = ClassLoader.getSystemClassLoader();
    Class loadClass = c.loadClass(name);
    System.out.println(loadClass);
}
類加載器應(yīng)用場景
  • 主要應(yīng)用于.class文件加密, 需要自身的類加載器來解密
  • .class文件是特殊路徑,系統(tǒng)不知道,只能用類加載器

注意事項(xiàng)

  • 提供的類名是全限定類名(Class.forName或者類加載器獲取類對(duì)象)
  • Class.forName可能拋出ClassNotFoundException

使用場景

(一) 創(chuàng)建任意類型對(duì)象

方式一 使用Class對(duì)象.newInstance(parameters)

步驟
  • 獲取這個(gè)類型的類對(duì)象
  • 通過這個(gè)類對(duì)象.newInstance()創(chuàng)建出對(duì)應(yīng)對(duì)象.
    • 這個(gè)類型必須有一個(gè)公共的無參構(gòu)造器.
示例代碼
@Test
public void testNewInstanceMethod1_2() {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream("properties.properties");
        Properties properties = new Properties();
        properties.load(fis);

        String className =  properties.getProperty("student");
        Class classObject = Class.forName(className);

        Object stu = classObject.newInstance();
        System.out.println(stu);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } finally {

        if (null != fis) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

@Test
public void testNewInstanceMethod1_1() {

    FileInputStream fis = null;
    try {
        fis = new FileInputStream("properties.properties");
        Properties properties = new Properties();
        properties.load(fis);

        String className =  properties.getProperty("typename");
        Class classObject = Class.forName(className);
        String str = (String) classObject.newInstance();

        System.out.println(classObject);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } finally {

        if (null != fis) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
特點(diǎn)
  • 這個(gè)類型必須有一個(gè)公共的無參構(gòu)造
    • 非公共的:IllegalAccessException
      沒有無參構(gòu)造:NoSuchMethodException 類型<init>()
  • 這個(gè)類型在運(yùn)行期間必須存在
    • 不存在 ClassNotFoundException

方式二 使用構(gòu)造器對(duì)象.newInstance(parameters)

步驟
  • 得到這個(gè)類型的class對(duì)象

  • 通過class對(duì)象, 獲取構(gòu)造器對(duì)象。

    • 可能有翠肘,可能沒有

      • 如果構(gòu)造器的訪問權(quán)限不允許檐束,那么可以使用如下方法,使得它可以被訪問

      構(gòu)造器對(duì)象.setAccessible(true)

  • 使用構(gòu)造器對(duì)象創(chuàng)建對(duì)應(yīng)的類型束倍。

    • 構(gòu)造器對(duì)象.newInstance(...)
示例代碼
    @Test
    public void testNewInstanceMethod2_1() {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("properties.properties");
            Properties properties = new Properties();
            properties.load(fis);

            String className =  properties.getProperty("student");
            Class classObject = Class.forName(className);

            Constructor constructor = classObject.getDeclaredConstructor(String.class, int.class);

            if (!constructor.isAccessible())
                constructor.setAccessible(true);
            Object o = constructor.newInstance("SweetCS", 26);
            System.out.println(o);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } finally {

            if (null != fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
特點(diǎn)
  • 如果夠照的訪問權(quán)限是不允許的被丧, 可以通過調(diào)用構(gòu)造器對(duì)象的setAccessible解決
    • 如果沒有會(huì)拋出 IllegalAccessException

(二)獲取類的任意信息

通過這個(gè)Class對(duì)象可以獲取這個(gè)類型的所有的信息
包盟戏、類名、修飾符甥桂、父類柿究、接口們、成員們:屬性黄选、構(gòu)造器蝇摸、方法、注解信息(必須是RetentionPolicy.RUNTIME

  • 關(guān)于屬性:
    修飾符糕簿、數(shù)據(jù)類型探入、屬性名、注解信息
  • 關(guān)于構(gòu)造器
    屬性能獲取+ 2(形參列表懂诗、拋出的異常列表)
  • 關(guān)于方法
    屬性能獲取 + 3(返回值類型蜂嗽、形參列表、拋出的異常列表)
public class TestClassInfo {

    @Test
    public void testClassInfo() throws ClassNotFoundException {

        Class managerClass = Class.forName("bean.Manager");

        // 獲取屬性信息 (訪問控制符(Modifilers) 類型 屬性名稱)
        System.out.println("fileds: ");
        Field[] fields = managerClass.getDeclaredFields();
        System.out.println("modifiler\ttype\tpropertyName");
        for (int i= 0; i <fields.length; i++) {
            Field field = fields[i];
            System.out.print(
                "|-"+ Modifier.toString(  + field.getModifiers()) + "-|" + "\t" +
                "|-"+  field.getType() + "-|" + "\t" +
                "|-"+ field.getName() + "-|"+ "\t");

            System.out.println();

            // 獲取注解
            String annotations =  StringUtils.join(field.getDeclaredAnnotations(), ",");
            if (StringUtils.trimToNull(annotations) != null)
                System.out.println("方法上的注解們:" + annotations);
        }

        // 構(gòu)造器比屬性少了一個(gè)類型
        System.out.println("construtors: ");
        Constructor[] constructors = managerClass.getConstructors();
        System.out.println("訪問控制符\t構(gòu)造器名稱");
        for (Constructor c :
             constructors) {
            System.out.println("|-" + Modifier.toString(c.getModifiers()) + "\t" + "-|" + "|-" +  c.getName()  + "-|" );

            String exceptions = StringUtils.join(c.getExceptionTypes(), ",");
            if (StringUtils.trimToNull(exceptions) != null)
                System.out.println("構(gòu)造器上的異常:" + exceptions);

        }


        // Method 就比屬性多了一個(gè)返回類型
        System.out.println("methods: ");
        Method[] methods =  managerClass.getDeclaredMethods();
        for (Method m :
             methods) {

            System.out.println("|-" + Modifier.toString(m.getModifiers()) + "-|"+ "\t"  +
                               "|-" + m.getReturnType() +  "-|"+"\t" +
                               "|-" +  m.getName() +"-|"+
                               "("+ StringUtils.join(m.getParameterTypes(), ",") + ")");


            // 獲取注解
            String annotations =  StringUtils.join(m.getDeclaredAnnotations(), ",");
            if (StringUtils.trimToNull(annotations) != null)
                System.out.println("方法上的注解們:" + annotations);
            String exceptions = StringUtils.join(m.getExceptionTypes(), ",");
            if (StringUtils.trimToNull(exceptions) != null)
                System.out.println("構(gòu)造器上的異常:" + exceptions);
        }

        // 其他
        // 獲取包名
        Package p = managerClass.getPackage();
        System.out.println("包名: " + p.getName());

        // 類訪問修飾符
        String modifierName = Modifier.toString(managerClass.getModifiers());
        System.out.println("類訪問修飾符:" + modifierName);


        // 父類
        Class superClass = managerClass.getSuperclass();
        System.out.println("父類:" + superClass);

        // 獲取實(shí)現(xiàn)的接口
        Class[] interfaces = managerClass.getInterfaces();
        for (Class i:
             interfaces) {
            System.out.println("接口:" + i);
        }
    }
}

輸出

fileds:
modifiler type propertyName
|-private static final-| |-long-| |-serialVersionUID-|
|-private-| |-double-| |-bonus-|
construtors:
訪問控制符 構(gòu)造器名稱
|-public -||-day23.bean.Manager-|
|-public -||-day23.bean.Manager-|
methods:
|-public-| |-class java.lang.String-| |-toString-|()
|-public-| |-int-| |-compareTo-|(class day23.bean.Manager)
|-public volatile-| |-int-| |-compareTo-|(class java.lang.Object)
|-public-| |-double-| |-getBonus-|()
|-public-| |-void-| |-setBonus-|(double)
方法上的注解們:@day23.bean.MyAnnotation(value=SweetCS)
包名: day23.bean
類訪問修飾符:public final
父類:class day23.bean.Employee
接口:interface java.io.Serializable
接口:interface java.lang.Comparabl

(三) 動(dòng)態(tài)設(shè)置和獲取屬性值

@Test
public void testFiled() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
    //假設(shè)Manager對(duì)象是在運(yùn)行期間創(chuàng)建的
    Class mangerClass = Class.forName("day23.bean.Manager");

    //obj代表一個(gè)經(jīng)理對(duì)象
    Object obj = mangerClass.newInstance();

    //2殃恒、設(shè)置obj這個(gè)經(jīng)理的獎(jiǎng)金值
    //(1)先得到獎(jiǎng)金屬性對(duì)象
    Field bounsField = mangerClass.getDeclaredField("bonus");                                    //"bonus"配置文件中配置

    //(2)設(shè)置屬性可操作,private屬性既不能使用反射直接setter也不能直接getter
    if (!bounsField.isAccessible()) bounsField.setAccessible(true);
    System.out.println("bonus :" + bounsField.get(obj));
    //(3)設(shè)置獎(jiǎng)金值
    bounsField.set(obj, 1000.0);

    //3植旧、獲取obj這個(gè)經(jīng)理的獎(jiǎng)金值
    System.out.println("bonus :" + bounsField.get(obj));
}

反射進(jìn)行屬性操作終結(jié)

  • 通過類對(duì)象獲取屬性對(duì)象(Field)
    • 最好用getDeclaredField來獲取屬性對(duì)象, 該方法私有屬性也能獲取
  • 如果是讀屬性, 調(diào)用 屬性對(duì)象.get(實(shí)例對(duì)象)
  • 如果是寫屬性, 調(diào)用 屬性對(duì)象.set(實(shí)例對(duì)象, 參數(shù))

注意: 如果屬性不可訪問, 設(shè)置屬性為accessible, 即可訪問

(四) 方法調(diào)用

反射技術(shù)還可以通過類對(duì)象來獲取這個(gè)對(duì)象所有的方法對(duì)象。java中方法對(duì)象使用Method表示离唐。所以我們可以通過類對(duì)象拿到Method對(duì)象, 來進(jìn)行方法的調(diào)用病附。

@Test
public void testMethodInvoke() throws Exception {
    // 假設(shè)Manager對(duì)象是在運(yùn)行期間創(chuàng)建的
    Class clazz = Class.forName("day23.bean.Manager");// 這個(gè)字符串可以從配置文件中獲取

    // obj代表一個(gè)經(jīng)理對(duì)象
    Object obj = clazz.newInstance();

    //調(diào)用obj經(jīng)理對(duì)象的setEId,setEName,setSalary等
    //(1)得到setName方法對(duì)象
    //參數(shù)一:方法名
    //參數(shù)二:方法的形參類型列表
    //因?yàn)榉椒赡苤剌d,所以需要用“方法名 + 形參列表”
    //"setEname", String.class通常也在xml文件中配置
    //getMethod可以得到這個(gè)類型的公共的方法包括從父類繼承的
    Method method = clazz.getMethod("setEname", String.class);//

    //(2)調(diào)用這個(gè)方法
    //參數(shù)一:哪個(gè)對(duì)象的method方法
    //參數(shù)二:該method方法需要的實(shí)參列表
    //invoke方法的返回值亥鬓,就是method方法調(diào)用后的返回值完沪,如果method方法沒有返回值,那么為null
    Object returnValue = method.invoke(obj, "張三");
    System.out.println(returnValue);

    //      (1)得到getName方法對(duì)象
    Method method2 = clazz.getMethod("getEname");
    //(2)調(diào)用
    Object value = method2.invoke(obj);
    System.out.println(value);
}

反射調(diào)用方法總結(jié)

  • 通過類對(duì)象, 拿到對(duì)應(yīng)的方法對(duì)象(Method)
    • 對(duì)于setter, 使用getMethod(方法名, 類對(duì)象列表). 這里的類對(duì)象列表是方法名的形參類型的類對(duì)象
    • 對(duì)于getter, 使用getMethod(方法名)
  • 調(diào)用invoke方法
    • 對(duì)于setter, 傳入實(shí)例對(duì)象(可以用類對(duì)象.newInstance()創(chuàng)建) 和 set的參數(shù)
    • 對(duì)于getter, 傳入實(shí)例對(duì)象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嵌戈,一起剝皮案震驚了整個(gè)濱河市覆积,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熟呛,老刑警劉巖宽档,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異庵朝,居然都是意外死亡吗冤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門九府,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椎瘟,“玉大人,你說我怎么就攤上這事昔逗〗荡” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵勾怒,是天一觀的道長婆排。 經(jīng)常有香客問我,道長笔链,這世上最難降的妖魔是什么段只? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮鉴扫,結(jié)果婚禮上赞枕,老公的妹妹穿的比我還像新娘。我一直安慰自己坪创,他們只是感情好炕婶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著莱预,像睡著了一般柠掂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上依沮,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天涯贞,我揣著相機(jī)與錄音,去河邊找鬼危喉。 笑死宋渔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辜限。 我是一名探鬼主播皇拣,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼薄嫡!你這毒婦竟也來了氧急?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤岂座,失蹤者是張志新(化名)和其女友劉穎态蒂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體费什,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钾恢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸳址。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘩蚪。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稿黍,靈堂內(nèi)的尸體忽然破棺而出疹瘦,到底是詐尸還是另有隱情,我是刑警寧澤巡球,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布言沐,位于F島的核電站邓嘹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏险胰。R本人自食惡果不足惜汹押,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望起便。 院中可真熱鬧棚贾,春花似錦、人聲如沸榆综。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鼻疮。三九已至怯伊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陋守,已是汗流浹背震贵。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留水评,地道東北人猩系。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像中燥,于是被迫代替她去往敵國和親寇甸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348