java反射使用总结

反射机制是什么

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制的优点与缺点

为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念

  • 静态编译:在编译时确定类型,绑定对象,即通过。
  • 动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,以降低类之间的藕合性。
优点:

可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,就需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。

缺点:

对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

理解反射

想要了解反射首先理解一下Class类,它是反射实现的基础。
类是java.lang.Class类的实例对象,而Class是所有类的类(There is a class named Class)
对于普通的对象,我们一般都会这样创建和表示:

Code code1 = new Code();
上面说了,所有的类都是Class的对象,那么如何表示呢,可不可以通过如下方式呢:

Class c = new Class();
但是我们查看Class的源码时,是这样写的:

private Class(ClassLoader loader) { 
classLoader = loader; 
} 

可以看到构造器是私有的,只有JVM可以创建Class的对象,因此不可以像普通类一样new一个Class对象,虽然我们不能new一个Class对象,但是却可以通过已有的类得到一个Class对象,共有三种方式,如下:

Class c1 = Code.class;
这说明任何一个类都有一个隐含的静态成员变量class,这种方式是通过获取类的静态成员变量class得到的

Class c2 = code1.getClass();
code1是Code的一个对象,这种方式是通过一个类的对象的getClass()方法获得的

Class c3 = Class.forName(“com.trigl.reflect.Code”);
这种方法是Class类调用forName方法,通过一个类的全量限定名获得

这里,c1、c2、c3都是Class的对象,他们是完全一样的,而且有个学名,叫做Code的类类型(class type)。
这里就让人奇怪了,前面不是说Code是Class的对象吗,而c1、c2、c3也是Class的对象,那么Code和c1、c2、c3不就一样了吗?为什么还叫Code什么类类型?这里不要纠结于它们是否相同,只要理解类类型是干什么的就好了,顾名思义,类类型就是类的类型,也就是描述一个类是什么,都有哪些东西,所以我们可以通过类类型知道一个类的属性和方法,并且可以调用一个类的属性和方法,这就是反射的基础。

举个简单例子代码:

public class ReflectDemo { 
public static void main(String[] args) throws ClassNotFoundException { 
    //第一种:Class c1 = Code.class; 
    Class class1=ReflectDemo.class; 
    System.out.println(class1.getName());

    //第二种:Class c2 = code1.getClass();
    ReflectDemo demo2= new ReflectDemo();
    Class c2 = demo2.getClass();
    System.out.println(c2.getName());

    //第三种:Class c3 = Class.forName("com.trigl.reflect.Code");
    Class class3 = Class.forName("com.tengj.reflect.ReflectDemo");
    System.out.println(class3.getName());
}
}

执行结果:

com.tengj.reflect.ReflectDemo 
com.tengj.reflect.ReflectDemo 
com.tengj.reflect.ReflectDemo 

反射机制能做什么

反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

Java 反射机制的应用场景

  • 逆向代码 ,例如反编译
  • 与注解相结合的框架 例如Retrofit
  • 单纯的反射机制应用框架 例如EventBus
  • 动态生成类框架 例如Gson

反射机制的相关API

InterFace 接口
package com.app;

public interface InterFace {

    void read() ;
    
}
Person 类
package com.app;

public class Person  implements InterFace {

    private String id ;

    private String name ;

    public String age ;
    
    //构造函数1
    public Person( ){

    }

    //构造函数2
    public Person( String id ){
        this.id = id ;
    }

    //构造函数3
    public Person( String id  , String name ){
        this.id = id ;
        this.name = name ;
    }


    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    /**
     * 静态方法
     */
    public static void update(){

    }


    @Override
    public void read() {

    }

}
  • 获取类:3种方法:
package com.app;

public class T1 {

    public static void main(String[] args) {

        //第一种方法:forName
        try {
            Class<?> class1 = Class.forName("com.app.Person");

            System.out.println( class1 );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


        //第二张方法:class
        Class<?> class2 = Person.class;  

        //第三种方法:getClass
        Person person = new Person();  
        Class<?> class3 = person.getClass();

        System.out.println( class2 );
        System.out.println( class3 );
    }

}

运行结果:

class com.app.Person
class com.app.Person
class com.app.Person
  • 获取所有的方法:getMethods( )
package com.app;

import java.lang.reflect.Method;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //获取所有的公共的方法
            Method[] methods =  class1.getMethods() ;
            
            for (Method method : methods) {
                System.out.println( method );
            }

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

运行结果:

//自定义方法
public static void com.app.Person.update()
public java.lang.String com.app.Person.getName()
public void com.app.Person.read()
public java.lang.String com.app.Person.getId()
public void com.app.Person.setName(java.lang.String)
public void com.app.Person.setId(java.lang.String)

//父类Object类方法
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
  • 获取所有实现的接口:getInterfaces()
package com.app;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //获取所有的接口
            Class<?>[] interS = class1.getInterfaces() ;

            for (Class<?> class2 : interS ) {
                System.out.println( class2 );
            }

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

运行结果:
interface com.app.InterFace

  • 获取父类:getSuperclass()
package com.app;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //获取父类
            Class<?> superclass = class1.getSuperclass() ;

            System.out.println( superclass );

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

运行结果:

//父类是Object类
class java.lang.Object
  • 获取所有的构造函数:getConstructors()
package com.app;

import java.lang.reflect.Constructor;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //获取所有的构造函数
            Constructor<?>[] constructors = class1.getConstructors() ;

            for (Constructor<?> constructor : constructors) {
                System.out.println( constructor );
            }


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

运行结果:

public com.app.Person(java.lang.String,java.lang.String)
public com.app.Person(java.lang.String)
public com.app.Person()
  • 获取所有的属性:getDeclaredFields();
package com.app;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //取得本类的全部属性
            Field[] field = class1.getDeclaredFields();

            for (Field field2 : field) {
                System.out.println( field2 );
            }

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

运行结果:

private java.lang.String com.app.Person.id
private java.lang.String com.app.Person.name

可以看出属性的修饰符是: private , 数据类型:String ,名字:id/name

  • 创建实例:newInstance()
package com.app;


public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");;

            //创建实例化:相当于 new 了一个对象
            Object object = class1.newInstance() ;

            //向下转型
            Person person = (Person) object ;

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

    }
}

getDeclaredFields 和 getFields 的区别

getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
getFields()获得某个类的所有的公共(public)的字段,包括父类。

小例子
package com.app;

import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");;

            //获得所有的字段属性:包括 
            Field[] declaredFields = class1.getDeclaredFields() ;

            Field[] fields = class1.getFields() ;

            for( Field field : declaredFields ){
                System.out.println( "de--  " +  field  );
            }

            for( Field field : fields ){
                System.out.println( "fields--  " +  field  );
            }

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

    }
}

运行结果:

de--  private java.lang.String com.app.Person.id
de--  private java.lang.String com.app.Person.name
de--  public java.lang.String com.app.Person.age
fields--  public java.lang.String com.app.Person.age

实战1:通过反射,获取对象实例,并且操作对象的方法

package com.app;


public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");;

            //创建实例化:相当于 new 了一个对象
            Object object = class1.newInstance() ;

            //向下转型              
            Person person = (Person) object ;
            
            person.setId( "100");
            person.setName( "jack") ; 
            
            System.out.println( "id: " + person.getId() + " name: " + person.getName()  );
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

运行结果:
id: 100 name: jack

实战2:通过反射获取对象字段属性,并且赋值

package com.app;

import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //创建实例
            Object person = class1.newInstance();

            //获得id 属性
            Field idField = class1.getDeclaredField( "id" ) ;
            
            //给id 属性赋值
            idField.set(  person , "100") ;

            //打印 person 的属性值
            System.out.println( idField.get( person ));

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace() ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

运行结果:

java.lang.IllegalAccessException: Class com.app.T1 can not access a member of class com.app.Person with modifiers "private"
    at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
    at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
    at java.lang.reflect.Field.set(Unknown Source)
    at com.app.T1.main(T1.java:20)

程序崩溃,原因是:id 这个属性的是 private 私有的,不能修改它的值。

改进:

添加 idField.setAccessible( true );

完整的代码为:

package com.app;

import java.lang.reflect.Field;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //创建实例
            Object person = class1.newInstance();

            //获得id 属性
            Field idField = class1.getDeclaredField( "id" ) ;

            //打破封装  实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问  
            //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的  
            idField.setAccessible( true );
            
            //给id 属性赋值
            idField.set(  person , "100") ;

            //打印 person 的属性值
            System.out.println( idField.get( person ));

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace() ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

运行结果:
100

实战3:综合训练,反射操作属性和方法

package com.app;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //创建实例
            Object person = class1.newInstance();

            //获得id 属性
            Field idField = class1.getDeclaredField( "id" ) ;

            //打破封装  实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问  
            //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的  
            idField.setAccessible( true );

            //给id 属性赋值
            idField.set(  person , "100") ;

            //获取 setName() 方法
            Method setName = class1.getDeclaredMethod( "setName", String.class ) ;
            //打破封装 
            setName.setAccessible( true );

            //调用setName 方法。
            setName.invoke( person , "jack" ) ;

            //获取name 字段
            Field nameField = class1.getDeclaredField( "name" ) ;
            //打破封装 
            nameField.setAccessible( true );

            //打印 person 的 id 属性值
            String id_ = (String) idField.get( person ) ;
            System.out.println( "id: " + id_ );

            //打印 person 的 name 属性值
            String name_ = ( String)nameField.get( person ) ;
            System.out.println( "name: " + name_ );
            
            //获取 getName 方法
            Method getName = class1.getDeclaredMethod( "getName" ) ;
            //打破封装 
            getName.setAccessible( true );
            
            //执行getName方法,并且接收返回值
            String name_2 = (String) getName.invoke( person  ) ;
            System.out.println( "name2: " + name_2 );

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace() ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

运行结果:

id: 100
name: jack
name2: jack

实战4:静态属性、静态方法调用

定义 Util 类
package com.app;

public class Util {

    public static String name = "json" ;

    /**
     * 没有返回值,没有参数
     */
    public static void getTips(){
        System.out.println( "执行了---------1111");
    }

    /**
     * 有返回值,没有参数
     */
    public static String getTip(){
        System.out.println( "执行了---------2222");
        return "tip2" ;
    }

    /**
     * 没有返回值,有参数
     * @param name
     */
    public static void getTip( String name ){
        System.out.println( "执行了---------3333 参数: " + name );
    }

    /**
     * 有返回值,有参数
     * @param id
     * @return
     */
    public static String getTip( int id ){
        System.out.println( "执行了---------4444 参数: " + id );
        if ( id == 0 ){
            return "tip1 444 --1 " ;
        }else{
            return "tip1 444 --2" ;
        }
    }

}
完整小例子:
package com.app;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class T1 {

    public static void main(String[] args) {

        try {
            //创建类
            Class<?> class1 = Class.forName("com.app.Util");

            //获取 nameField 属性
            Field nameField = class1.getDeclaredField( "name" ) ;
            //获取 nameField 的值
            String name_ = (String) nameField.get( nameField ) ;
            //输出值
            System.out.println( name_ );


            //没有返回值,没有参数
            Method getTipMethod1 = class1.getDeclaredMethod( "getTips"  ) ; 
            getTipMethod1.invoke( null  ) ;
            
            //有返回值,没有参数
            Method getTipMethod2 = class1.getDeclaredMethod( "getTip"  ) ; 
            String result_2 = (String) getTipMethod2.invoke( null  ) ;
            System.out.println( "返回值: "+ result_2 );
            
            //没有返回值,有参数
            Method getTipMethod3 = class1.getDeclaredMethod( "getTip" , String.class  ) ; 
            String result_3 = (String) getTipMethod3.invoke( null , "第三个方法"  ) ;
            System.out.println( "返回值: "+ result_3 );
            
            //有返回值,有参数
            Method getTipMethod4 = class1.getDeclaredMethod( "getTip" , int.class ) ; 
            String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
            System.out.println( "返回值: "+ result_4 );
            
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace() ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

运行结果:

json
执行了---------1111
执行了---------2222
返回值: tip2
执行了---------3333 参数: 第三个方法
返回值: null
执行了---------4444 参数: 1
返回值: tip1 444 --2

当参数是 int 类型 和 Integer 类型,反射获取方法不一样

  • 当参数是 int 类型时
/**
     * 没有返回值,有参数
     * @param id
     */
    public static void getTip( int id ){
        
    }

获取方法的时候需要用:int.class。不能使用 Integer.class. 会报错。

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , int.class ) ; 
String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
System.out.println( "返回值: "+ result_4 );
  • 当参数是 Integer类型时
    /**
     * 没有返回值,有参数
     * @param id
     */
    public static void getTip( Integer id ){
        
    }

获取方法的时候需要用:Integer .class。不能使用 int.class. 会报错。

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , Integer .class ) ; 
String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
System.out.println( "返回值: "+ result_4 );

创建对象实例

Person 类
package com.app;

public class Person{

    private String id ;

    private String name ;


    //构造函数1
    public Person( ){
        System.out.println( "构造函数  无参" );
    }

    //构造函数2
    public Person( String id ){
        this.id = id ;
        System.out.println( "构造函数 id : " + id );
    }

    //构造函数3
    public Person( String id  , String name ){
        this.id = id ;
        this.name = name ;
        System.out.println( "构造函数 id : " + id  + " name: " + name );
    }


    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
创建实例实战
package com.app;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class T1 {

    public static void main(String[] args) {

        try {
            
            //创建类
            Class<?> class1 = Class.forName("com.app.Person");

            //无参构造函数
            Object object = class1.newInstance() ;
            
            //有参构造函数:一个参数
            Constructor<?> constructor =  class1.getDeclaredConstructor( String.class ) ;
            constructor.newInstance( "1000" ) ;
            
            //有参构造函数:二个参数
            Constructor<?> constructor2 =  class1.getDeclaredConstructor( String.class , String.class ) ;
            constructor2.newInstance( "1001" , "jack" ) ;

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace() ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

运行结果:

构造函数  无参
构造函数 id : 1000
构造函数 id : 1001 name: jack

总结

  • Class类提供了四个public方法,用于获取某个类的构造方法。
Constructor getConstructor(Class[] params)     根据构造函数的参数,返回一个具体的具有public属性的构造函数
Constructor getConstructors()     返回所有具有public属性的构造函数数组
Constructor getDeclaredConstructor(Class[] params)     根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
Constructor getDeclaredConstructors()    返回该类中所有的构造函数数组(不分public和非public属性)
  • 四种获取成员方法的方法
Method getMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的具有public属性的方法
Method[] getMethods()    返回所有具有public属性的方法数组
Method getDeclaredMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的方法(不分public和非public属性)
Method[] getDeclaredMethods()    返回该类中的所有的方法数组(不分public和非public属性)
  • 四种获取成员属性的方法
Field getField(String name)    根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields()    返回具有public属性的成员变量的数组
Field getDeclaredField(String name)    根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredField()    返回所有成员变量组成的数组(不分public和非public属性)

转载自:
http://www.cnblogs.com/zhaoyanjun/p/6074887.html
也可参考更详细的反射知识:
http://www.daidingkang.cc/2017/07/18/java-reflection-annotations/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够...
    java部落阅读 154评论 0 0
  • 声明:原创文章,转载请注明出处。http://www.jianshu.com/p/b4757a970b26 一、概...
    唐影若凡阅读 221评论 0 1
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,093评论 1 32
  • (这是我今天早上发生的事) 自从放假以后,我就像变了一个人,心里有许多的不知所措,让我也方寸大乱,失眠了很...
    AI琳姐姐阅读 310评论 2 3
  • 先查询下他自动生成的二维码文件夹,是否生成了二维码。如果没有找到那个文件夹,说明没有自动生成二维码的文件夹,这个时...
    iiiiiiii1阅读 690评论 0 0