Java反射-1(理論)

Java反射-1(理論)
Java反射-2(技巧)
JAVA反射-3(性能)

什么叫做反射?反射有什么用怎炊?這篇文章會(huì)娓娓道來(lái)壁肋。
咱們就先從反射官網(wǎng)入手,開(kāi)始解讀下吧印荔。

1. 官網(wǎng)解讀:

1.1 什么叫做反射

Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.

反射通常是被程序使用惜辑,這些程序需要能夠檢查或修改運(yùn)行在JVM的應(yīng)用程序的運(yùn)行時(shí)行為优俘。

1.1.1 反射的優(yōu)點(diǎn)

Extensibility Features
An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.

可擴(kuò)展功能
應(yīng)用程序可使用 完全限定的名稱 創(chuàng)建 可擴(kuò)展對(duì)象的實(shí)例 來(lái)使用外部或用戶定義的類(lèi)。

1.1.2 反射的缺點(diǎn)

Performance Overhead
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

性能開(kāi)銷(xiāo)
由于反射設(shè)計(jì)到動(dòng)態(tài)解析的類(lèi)型,因此無(wú)法執(zhí)行某些JVM的優(yōu)化籍琳。因此先舷,反射操作性能低于非反射操作,應(yīng)該避免在性能敏感的程序中頻繁調(diào)用前方。

Exposure of Internals
Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

內(nèi)部暴露
由于反射允許代碼執(zhí)行非法的操作在非反射代碼中狈醉,例如,訪問(wèn)私有字段或方法惠险,因此使用反射可能導(dǎo)致意外的副作用苗傅,可能導(dǎo)致代碼功能失常并可能失去可移植性,反射代碼打破了抽象莺匠,因此使用反射的代碼可能會(huì)在系統(tǒng)升級(jí)后表現(xiàn)異常金吗。

Security Restrictions
Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.

安全限制
反射需要運(yùn)行時(shí)的權(quán)限,因此無(wú)法在安全管理器下運(yùn)行,必須受限于安全的上下文中運(yùn)行摇庙,例如Applet旱物,只是一個(gè)重要的考慮因素。

1.2 Class對(duì)象的學(xué)習(xí)

Every type is either a reference or a primitive.

每一種對(duì)象都是引用類(lèi)型或者基本數(shù)據(jù)類(lèi)型卫袒。

For every type of object, the Java virtual machine instantiates an immutable instance of java.lang.Class which provides methods to examine the runtime properties of the object including its members and type information. Class also provides the ability to create new classes and objects. Most importantly, it is the entry point for all of the Reflection APIs.

對(duì)于每一種對(duì)象的類(lèi)型宵呛,JVM提供了一個(gè)不可變對(duì)象,java.lang.Class不可變對(duì)象提供了檢查運(yùn)行時(shí)對(duì)象 成員和類(lèi)型信息的方法夕凝。還提供了創(chuàng)建類(lèi)和對(duì)象的功能宝穗。最重要的,他是反射API的入口點(diǎn)码秉。

1.2.1 getClass()語(yǔ)法

If an instance of an object is available, then the simplest way to get its Class is to invoke Object.getClass(). Of course, this only works for reference types which all inherit from Object.

對(duì)象是可用的情況:得到它的class對(duì)象最簡(jiǎn)單的方法就是object.getClass()逮矛,當(dāng)然,這僅僅適用于繼承與object下的類(lèi)转砖。

  public static void main(String[] args) {
        Heap heap = new Heap();
        System.out.println("普通對(duì)象的返回類(lèi)型:" + heap.getClass());
        //注意须鼎,聲明類(lèi)型  xx=new 實(shí)際類(lèi)型();返回的是實(shí)際類(lèi)型
        Set set = new HashSet();
        System.out.println("實(shí)際類(lèi)型的返回類(lèi)型:" + set.getClass());
        //注意數(shù)據(jù)的返回類(lèi)型
        byte[] bytes = new byte[1024];
        System.out.println("數(shù)組的返回類(lèi)型:" + bytes.getClass());
        System.out.println("枚舉的返回類(lèi)型:"+enums.RED.getClass());
    }

執(zhí)行結(jié)果:

getClass()的返回結(jié)果

1.2.2 .class語(yǔ)法

If the type is available but there is no instance then it is possible to obtain a Class by appending ".class" to the name of the type.

如果類(lèi)型可用但沒(méi)有對(duì)象:可以通過(guò)Class附帶的".class"名稱獲取Class對(duì)象。

.class對(duì)象獲取Class對(duì)象

1.2.3 Class.forName()語(yǔ)法

If the fully-qualified name of a class is available, it is possible to get the corresponding Class using the static method Class.forName(). This cannot be used for primitive types.

一個(gè)類(lèi)的完全限定名可用:可以使用靜態(tài)方法Class.forName()去創(chuàng)建Class對(duì)象府蔗,不能用于基本數(shù)據(jù)類(lèi)型晋控。

1.2.4 Type用法

The .class syntax is a more convenient and the preferred way to obtain the Class for a primitive type; however there is another way to acquire the Class. Each of the primitive types and void has a wrapper class in java.lang that is used for boxing of primitive types to reference types. Each wrapper class contains a field named TYPE which is equal to the Class for the primitive type being wrapped.

對(duì)于基本數(shù)據(jù)類(lèi)型.class方式是一種便捷的姓赤、首選的方式來(lái)獲取Class對(duì)象赡译。然而有另一種方法去創(chuàng)建Class對(duì)象。每一種基本數(shù)據(jù)類(lèi)型和void都有一個(gè)包裝類(lèi)java.lang不铆。用于將基本數(shù)據(jù)類(lèi)型裝箱蝌焚。每一個(gè)包裝類(lèi)包含一個(gè)TYPE的域,該字段等于Class被包裝的基本類(lèi)型狂男。

對(duì)于非基本數(shù)據(jù)類(lèi)型综看,返回的是編譯錯(cuò)誤。

非基本數(shù)據(jù)類(lèi)型

測(cè)試代碼:

    public static void main(String[] args) {
        Class dobClass = Double.TYPE;
        //Void也有封裝類(lèi)型岖食!
        Class voidClass=Void.TYPE;
        System.out.println(dobClass);
        System.out.println(voidClass);
    }

輸出結(jié)果:

TYPE字段

1.2.5 返回Class的方法

There are several Reflection APIs which return classes but these may only be accessed if a Class has already been obtained either directly or indirectly.

有幾個(gè)Reflection API可以返回classes對(duì)象红碑,但只有Class對(duì)象直接或者間接獲取的情況下。
下面getclasses()知識(shí)點(diǎn)需要用到成員內(nèi)部類(lèi)泡垃,可以先了解下析珊。

    public static void main(String[] args) {
        //返回作為類(lèi)成員的所有公共類(lèi),接口和枚舉蔑穴,包括繼承的成員忠寻。
        Class<?>[] dobClass = HashMap.class.getClasses();
        for (Class c : dobClass) {
            System.out.println("類(lèi)或其父類(lèi)所有成員public內(nèi)部類(lèi):" + c);
        }
        Class<?>[] declaredClasses = HashMap.class.getDeclaredClasses();
        for (Class c1 : declaredClasses) {
            System.out.println("本類(lèi)所有成員內(nèi)部類(lèi):"+c1);
        }
    }

執(zhí)行結(jié)果:

getClasses()和getDeclaredClasses()代碼

下面這個(gè)類(lèi)實(shí)現(xiàn)了:獲取類(lèi)的聲明組件,包括修飾符存和,泛型類(lèi)型參數(shù)奕剃,實(shí)現(xiàn)的接口和繼承路徑衷旅。由于 Class實(shí)現(xiàn)了java.lang.reflect.AnnotatedElement接口,因此還可以查詢運(yùn)行時(shí)注釋纵朋。

public class Reflect {
    public static void main(String[] args) {
        try {
            Class<?> c = Class.forName("Algorithm.Outer");
            out.println("Class:" + c.getCanonicalName());
            out.println("訪問(wèn)修飾符:" + Modifier.toString(c.getModifiers()));
            TypeVariable<? extends Class<?>>[] tv = c.getTypeParameters();
            if (tv.length != 0) {
                for (TypeVariable t : tv) {
                    out.println("泛型類(lèi)型:" + t.getName());
                }
                out.println();
            } else {
                out.println("--無(wú)泛型的參數(shù)類(lèi)型--");
            }
            //獲取接口類(lèi)型
            Type[] intfs = c.getGenericInterfaces();
            if (intfs.length != 0) {
                for (Type intf : intfs)
                    out.println("接口類(lèi)型:" + intf.toString());
            } else {
                out.format("--無(wú)接口類(lèi)型--");
            }

            //將父類(lèi)保存到List集合里面
            List<Class> l = new ArrayList<Class>();
            printAncestor(c, l);
            if (l.size() != 0) {
                for (Class<?> cl : l)
                    //打印父類(lèi)名稱
                    out.println("父類(lèi)名稱:" + cl.getCanonicalName());
            } else {
                out.format("--沒(méi)有父類(lèi)名稱--");
            }
            Annotation[] ann = c.getAnnotations();
            if (ann.length != 0) {
                for (Annotation a : ann)
                    out.println("注釋信息:" + a.toString());
            } else {
                out.format(" --沒(méi)有注釋信息--");
            }
            // production code should handle this exception more gracefully
        } catch (ClassNotFoundException x) {
            x.printStackTrace();
        }
    }

    //遞歸方法柿顶,返回所以的父類(lèi)類(lèi)型,直至Object類(lèi)
    private static void printAncestor(Class<?> c, List<Class> l) {
        Class<?> ancestor = c.getSuperclass();
        if (ancestor != null) {
            l.add(ancestor);
            printAncestor(ancestor, l);
        }
    }
}

Since arrays are runtime objects, all of the type information is defined by the Java virtual machine. In particular, arrays implement Cloneable andjava.io.Serializable and their direct superclass is always Object.

由于數(shù)組是運(yùn)行時(shí)對(duì)象操软,因此所有的類(lèi)型信息都由JVM定義的嘁锯。特別是,數(shù)組實(shí)現(xiàn)Clonablejava.io.Serializable聂薪,他的直接超類(lèi)總是Object家乘;

2. 源碼實(shí)現(xiàn)

將XML數(shù)據(jù)轉(zhuǎn)化為Object對(duì)象,將Object對(duì)象轉(zhuǎn)化為XML文件藏澳。

/**
     * XML轉(zhuǎn)化為Object
     * 
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public final static void objectFromXml(Object obj, String xml) throws InstantiationException,
            IllegalAccessException {
        Element root = parseXml(xml);
        Class clazz = obj.getClass();
        do
            objectFromXml(obj, clazz, root);
        while ((clazz = clazz.getSuperclass()) != null);
    }

    public final static void objectFromXml(Object obj, Class clazz, Element root)
            throws InstantiationException, IllegalAccessException {
        if (root == null || (root.elements()).size() == 0) {
            return;
        }
        // 獲取私有變量
        Field[] fields = clazz.getDeclaredFields();
        // 暴力解除
        Field.setAccessible(fields, true);
        for (Field field : fields) {
            // field.getModififers()獲取
            String name = field.getName();
            Class type = field.getType();
            // 內(nèi)省機(jī)制仁锯,證明該字段在此對(duì)象里面是可編輯的
            if ((!Modifier.isStatic(field.getModifiers())) && PropertyUtils.isWriteable(obj, name)) {
                // 獲取屬性的類(lèi)型
                // 判斷類(lèi)型來(lái)自哪里(可指定的)
                if (type.isAssignableFrom(List.class)) {
                    // 獲取屬性的Type類(lèi)型
                    Type genericType = field.getGenericType();
                    List<Element> elements = root.elements(name);
                    // 根本沒(méi)有這個(gè)節(jié)點(diǎn)的話,那么不予賦值
                    if ((elements == null) && elements.size() == 0) {
                        continue;
                    }
                    // 判斷該Type類(lèi)型是不是參數(shù)化的文件
                    if (genericType instanceof ParameterizedType) {
                        ParameterizedType pt = (ParameterizedType) genericType;
                        Class parameterizedClass = (Class) pt.getActualTypeArguments()[0];
                        // 想當(dāng)與new了一個(gè)對(duì)象
                        List lists = new ArrayList();
                        for (Element ele : elements) {
                            Object object = parameterizedClass.newInstance();
                            // 判斷泛型是否是基本數(shù)據(jù)對(duì)象
                            if (isPrimitiveType(parameterizedClass)) {
                                // 將element里面的對(duì)象賦值到反射出的對(duì)象里面
                                object = setObjectValue(object, ele.getText());
                            } else {
                                // 迭代笆载,無(wú)論執(zhí)行都少次扑馁,最后一次,將正確的值返回
                                objectFromXml(object, parameterizedClass, ele);
                            }
                            lists.add(object);
                        }
                        // 將obj對(duì)象的List集合賦值
                        field.set(obj, lists);
                    }
                } else {
                    // 若不包含改節(jié)點(diǎn)
                    String text = root.elementText(name);
                    if (null != text) {
                        try {
                            if (isPrimitiveType(field.getType())) {
                                setObjectValue(obj, field, text);
                            } else {
                                // 創(chuàng)建改屬性的object凉驻、class、節(jié)點(diǎn)
                                Object fieldObject = type.newInstance();
                                Element fieldRoot = root.element(name);
                                objectFromXml(fieldObject, type, fieldRoot);
                                // 為obj對(duì)象里面的field屬性賦予fieldObject對(duì)象的值
                                field.set(obj, fieldObject);
                            }
                        } catch (NumberFormatException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IllegalArgumentException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (ParseException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

Object轉(zhuǎn)化為XML:

public static void ObjectToXML(Object obj, Element root) throws IllegalArgumentException,
            IllegalAccessException, SecurityException, NoSuchMethodException,
            InvocationTargetException, ParseException {
        // 創(chuàng)建Class對(duì)象
        Class clazz = obj.getClass();
        do
            ObjectToXML(obj, clazz, root);
        while ((clazz = clazz.getSuperclass()) != null);
    }

    public static void ObjectToXML(Object obj, Class clazz, Element root)
            throws IllegalArgumentException, IllegalAccessException, SecurityException,
            NoSuchMethodException, InvocationTargetException, ParseException {
        Field[] fields = clazz.getDeclaredFields();
        Field.setAccessible(fields, true);
        for (Field field : fields) {
            // 判斷是否是List
            Class fieldClass = field.getType();
            String name = field.getName();
            Object descObj = field.get(obj);
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            if (descObj == null) {
                if (isPrimitiveType(fieldClass)) {
                    descObj = "";
                } else {
                    continue;
                }
            }
            if (fieldClass.isAssignableFrom(List.class)) {
                Type genType = field.getGenericType();
                if (genType instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) genType;
                    Class paramClass = (Class) pt.getActualTypeArguments()[0];
                    System.out.println("List的泛型對(duì)象:" + paramClass);
                    String paramText = null;
                    // 判斷參數(shù)的類(lèi)型
                    List paramList = (ArrayList) descObj;
                    // foreach循環(huán)前需要加判斷
                    if (paramList == null || paramList.size() == 0 || paramClass == null) {
                        continue;
                    }
                    Method m = fieldClass.getDeclaredMethod("size", new Class[0]);
                    Integer size = (Integer) m.invoke(descObj, new Object[0]);
                    root.addElement(name + "_NUM").setText(size + "");
                    Element childEle = null;
                    // 獲取list集合里面的對(duì)象
                    for (Object object : paramList) {
                        if (isPrimitiveType(paramClass)) {
                            childEle = root.addElement(name);
                            root.addText(String.valueOf(getObjectValue(object, paramClass)));
                        } else {
                            childEle = new DOMElement(name);
                            ObjectToXML(object, childEle);
                            root.add(childEle);
                        }
                    }
                }
            } else if (fieldClass.isAssignableFrom(Map.class)) {
                Map map = (Map) descObj;
                Type mapGentype = field.getGenericType();
                // 若是泛型類(lèi)型
                if (mapGentype instanceof ParameterizedType) {
                    ParameterizedType mapPt = (ParameterizedType) mapGentype;
                    Class keyClass = (Class) mapPt.getActualTypeArguments()[0];
                    Type valueType = mapPt.getActualTypeArguments()[1];
                    Class valueClass = (Class) valueType;
                    Iterator<Map.Entry> it = map.entrySet().iterator();
                    // 默認(rèn)Key是基本類(lèi)型
                    while (it.hasNext()) {
                        Entry entry = it.next();
                        Object keyObject = entry.getKey();
                        System.out.println("map的key:" + keyObject);
                        Object valueObject = entry.getValue();
                        System.out.println("map的value:" + valueObject.getClass());
                        Element mapEle = null;
                        // 設(shè)置到XML里面
                        String keyName = null;
                        if (isPrimitiveType(keyClass)) {
                            keyName = (String) getObjectValue(keyObject, keyClass);
                        } else {
                            continue;
                        }
                        if (isPrimitiveType(valueClass)) {
                            mapEle = root.addElement(keyName); // 創(chuàng)建節(jié)點(diǎn)
                            mapEle.setText((String) getObjectValue(valueObject, valueClass));
                        } else {
                            // 若是對(duì)象
                            mapEle = new DOMElement(keyName);
                            Element childEle = null;
                            if (valueObject instanceof List) {
                                // 若是list集合复罐,直接繼續(xù)賦值
                                List mapList = (ArrayList) valueObject;
                                if (mapList == null || map.size() == 0) {
                                    continue;
                                }
                                Class cls = mapList.get(0).getClass(); // 獲取List對(duì)象的泛型的對(duì)象類(lèi)型
                                for (Object object : mapList) {
                                    if (isPrimitiveType(cls)) {
                                        childEle = root.addElement(name);
                                        mapEle.addText(String.valueOf(getObjectValue(object, cls)));
                                    } else {
                                        childEle = new DOMElement(name);
                                        ObjectToXML(object, childEle);
                                        mapEle.add(childEle);
                                    }
                                }
                            } else {
                                ObjectToXML(valueObject, mapEle);
                            }
                            root.add(mapEle);
                        }
                    }
                }
            } else {
                // 屬性字段是否是普通對(duì)象普通對(duì)象
                Element childEle = new DOMElement(name);
                if (isPrimitiveType(fieldClass)) {
                    childEle.setText(String.valueOf(getObjectValue(descObj, fieldClass)));
                } else {
                    ObjectToXML(descObj, childEle);
                }
                root.add(childEle);
            }
        }
    }

工具類(lèi):

/**
     * 解析Element節(jié)點(diǎn)
     * 
     * @param xml
     * @return
     */
    private static Element parseXml(String xml) {
        Element root = null;
        try {
            Document doc = DocumentHelper.parseText(xml);
            root = doc.getRootElement();
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return root;
    }

    /**
     * 
     * @param object
     *            目標(biāo)對(duì)象
     * @param field
     *            目標(biāo)對(duì)象的反射字段
     * @param text
     *            需要反射字段賦予的值
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws NumberFormatException
     * @throws ParseException
     */
    private static void setObjectValue(Object object, Field field, String text)
            throws NumberFormatException, IllegalArgumentException, IllegalAccessException,
            ParseException {
        if (object == null || field == null) {
            return;
        }
        // 獲取反射字段的Class對(duì)象涝登。getClass()返回的是Field對(duì)象
        Class fieldClass = field.getType();
        if (fieldClass.isAssignableFrom(long.class) || fieldClass.isAssignableFrom(Long.class)) {
            field.set(object, Long.valueOf(text));
        } else if (fieldClass.isAssignableFrom(int.class)
                || fieldClass.isAssignableFrom(Integer.class)) {
            field.set(object, Integer.valueOf(text));
        } else if (fieldClass.isAssignableFrom(double.class)
                || fieldClass.isAssignableFrom(Double.class)) {
            field.set(object, Double.valueOf(text));
        } else if (fieldClass.isAssignableFrom(float.class)
                || fieldClass.isAssignableFrom(Float.class)) {
            field.set(object, Float.valueOf(text));
        } else if (fieldClass.isAssignableFrom(boolean.class)
                || fieldClass.isAssignableFrom(Boolean.class)) {
            field.set(object, Boolean.valueOf(text));
        } else if (fieldClass.isAssignableFrom(Date.class)) {
            DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
            field.set(object, df.parse(text));
        } else if (fieldClass.isAssignableFrom(String.class)) {
            field.set(object, text);
        } else if (fieldClass.isArray()) {
            field.set(object, text.toCharArray());
        } else {
            field.set(object, text);
        }
    }

    private static Object getObjectValue(Object object, Class paramsClass)
            throws IllegalArgumentException, IllegalAccessException, ParseException {
        if (object == null) {
            return null;
        }
        if (paramsClass.isAssignableFrom(Date.class)) {
            DateFormat dt = new SimpleDateFormat("yyyyMMddhhmmss");
            object = dt.format(object);
        } else if (paramsClass.isAssignableFrom(Double.class)
                || paramsClass.isAssignableFrom(double.class)) {
            // double類(lèi)型格式化
            NumberFormat nf = NumberFormat.getNumberInstance();
            nf.setMaximumFractionDigits(8);
            object = nf.format((Double) object);
        } else {
            object = String.valueOf(object);
        }
        return object;
    }

    // 返回泛型(反射的new)對(duì)象的值 。
    private static Object setObjectValue(Object object, String text) {
        if (object == null)
            return null;
        Class clazz = object.getClass();
        if (clazz.isAssignableFrom(long.class) || clazz.isAssignableFrom(Long.class)) {
            object = Long.valueOf(text);
        } else if (clazz.isAssignableFrom(int.class) || clazz.isAssignableFrom(Integer.class)) {
            object = Integer.valueOf(text);
        } else if (clazz.isAssignableFrom(double.class) || clazz.isAssignableFrom(Double.class)) {
            object = Double.valueOf(text);
        } else if (clazz.isAssignableFrom(float.class) || clazz.isAssignableFrom(Float.class)) {
            object = Float.valueOf(text);
        } else if (clazz.isAssignableFrom(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
            object = Boolean.valueOf(text);
        } else if (clazz.isAssignableFrom(Date.class)) {
            DateFormat df = new SimpleDateFormat("yyyymmddhhmiss");
            try {
                object = df.parse(text);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            object = text;
        }
        return object;
    }

    // 將其超類(lèi)刪除
    private static boolean isPrimitiveType(Class<?> clazz) {
        boolean isPrimitiveOrPrimitiveClass = Boolean.valueOf(false);
        if ((!clazz.isAssignableFrom(Object.class))
                && ((clazz.isPrimitive() || clazz.isAssignableFrom(Double.class)
                        || clazz.isAssignableFrom(Float.class)
                        || clazz.isAssignableFrom(Long.class)
                        || clazz.isAssignableFrom(Integer.class)
                        || clazz.isAssignableFrom(Boolean.class)
                        || clazz.isAssignableFrom(Byte.class)
                        || clazz.isAssignableFrom(Character.class)
                        || clazz.isAssignableFrom(Short.class)
                        || clazz.isAssignableFrom(String.class) || clazz
                            .isAssignableFrom(Date.class)))) {
            isPrimitiveOrPrimitiveClass = Boolean.valueOf(true);
        }
        return isPrimitiveOrPrimitiveClass;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末效诅,一起剝皮案震驚了整個(gè)濱河市胀滚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乱投,老刑警劉巖咽笼,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異戚炫,居然都是意外死亡剑刑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)双肤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)施掏,“玉大人,你說(shuō)我怎么就攤上這事茅糜∑甙牛” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵蔑赘,是天一觀的道長(zhǎng)狸驳。 經(jīng)常有香客問(wèn)我预明,道長(zhǎng),這世上最難降的妖魔是什么耙箍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任贮庞,我火速辦了婚禮,結(jié)果婚禮上究西,老公的妹妹穿的比我還像新娘窗慎。我一直安慰自己,他們只是感情好卤材,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布遮斥。 她就那樣靜靜地躺著,像睡著了一般扇丛。 火紅的嫁衣襯著肌膚如雪术吗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天帆精,我揣著相機(jī)與錄音较屿,去河邊找鬼。 笑死卓练,一個(gè)胖子當(dāng)著我的面吹牛隘蝎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播襟企,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嘱么,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了顽悼?” 一聲冷哼從身側(cè)響起曼振,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔚龙,沒(méi)想到半個(gè)月后冰评,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡木羹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年甲雅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汇跨。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡务荆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出穷遂,到底是詐尸還是另有隱情函匕,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布蚪黑,位于F島的核電站盅惜,受9級(jí)特大地震影響中剩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抒寂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一结啼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屈芜,春花似錦郊愧、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至躬翁,卻和暖如春焦蘑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盒发。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工例嘱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宁舰。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓拼卵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親明吩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子间学,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,294評(píng)論 0 10
  • 01 人間的新年要比天宮有趣得多。 作為六界里所剩不多印荔,已成為稀罕物的上神,我自然被請(qǐng)去了天庭盛宴详羡,哪怕只為天君添...
    gio33閱讀 426評(píng)論 18 6
  • 笑面鐵人 最近"我不是藥神"這部電影火爆了仍律,不每一部火的電影背后,都有其群眾基礎(chǔ)实柠,這個(gè)群眾基礎(chǔ)水泉,并不是明星的粉絲數(shù)...
    笑面鐵人閱讀 93評(píng)論 0 0
  • 2011-03-30 18:50 天空一片泛藍(lán) 再找不到久違的 感覺(jué) 當(dāng)人生一片空白 該如何填補(bǔ)所有內(nèi)容 后悔當(dāng)初...
    歐陽(yáng)默閱讀 124評(píng)論 0 0