JAVA反射機制詳解

1.理解反射的基礎:Class類

眾所周知Java有個Object 類靶壮,是所有Java 類的繼承根源,其內聲明了數個應該在所有Java 類中被改寫的方法:hashCode()员萍、equals()腾降、clone()、toString()碎绎、getClass()等螃壤。其中getClass()返回一個Class 對象抗果。

Class 類十分特殊。它和一般類一樣繼承自Object映穗,其實體用以表達Java程序運行時的classes和interfaces,也用來表達enum幕随、array蚁滋、primitive Java types(boolean, byte, char, short, int, long, float, double)以及關鍵詞void。當一個class被加載赘淮,或當加載器(class loader)的defineClass()被JVM調用辕录,JVM 便自動產生一個Class 對象。如果您想借由“修改Java標準庫源碼”來觀察Class 對象的實際生成時機(例如在Class的constructor內添加一個println())梢卸,這樣是行不通的走诞!因為Class并沒有public constructor。

Class是Reflection故事起源蛤高。針對任何您想探勘的類厨埋,唯有先為它產生一個Class 對象屹徘,接下來才能經由后者喚起為數十多個的Reflection APIs。這些APIs將在稍后的探險活動中一一亮相。

Java類用于描述一類事物的共性据悔,該類事物有什么屬性,至于這個類的屬性值是什么导犹,則是由這個類的對象來確定尔艇,不同的實例對象有不同的屬性值。java程序中的各個類喜庞,他們也屬于同一類事物诀浪,也可以用一個類來描述這類事物,這個類就是Class延都,要注意和小寫的class關鍵字的區(qū)別雷猪。Class類描述那些方面的信息呢?類的名字晰房,類的訪問屬性春宣,類所屬于的包名,字段名稱的列表嫉你,方法名稱的列表月帝,等等,學習反射幽污,首先要明白這個Class類嚷辅。

對比提問1:眾多的人用一個什么類表示?眾多的java類用什么表示距误?
人-》Person
Java類-》Class
此時很明顯的體現(xiàn)了java面向對象的思想(一切皆為對象)簸搞。

對比提問2:Person類代表人扁位,他的實例對象就是張三,李四這樣一個個具體的人趁俊,Class類代表java類域仇,那么他的實例對象又分別對應什么呢?
對應的是各個類在內存中的字節(jié)碼(一個類有且僅有一份)寺擂,例如暇务,Person類的字節(jié)碼,ArrayList類的字節(jié)碼等等怔软。(字節(jié)碼就是類被加載到jvm中內存中的Class類的實例垦细,然后利用這個字節(jié)碼復制一個個指定類的對象)。

一個類被類加載器加載到內存中挡逼,占用一片存儲空間括改,這個空間里邊的內容就是類的字節(jié)碼,不同的類的字節(jié)碼是不同的家坎,所以他在內存中的內容是不同的嘱能,這一個個的空間分別用一個個對象來表示,這些對象顯示具有相同的類型虱疏,這個類型是什么呢焰檩?就是 Class類。

三種獲取Class對象的方法:
不能用Class c = new Class(),沒有這個構造方法的订框,應該采取下邊的三種方法:
1).  Person.class 類名.class的方式;
2).  Person p = new Person; p.getClass(); person類的實例getClass的方式;
3).  Class.forName(“類名(全路徑)”); 這個如果在jvm內存中沒有找到指定類的字節(jié)碼析苫,就先將指定類加載到jvm內存中,然后在返回指定的類的Class實例穿扳,如果jvm中存在就直接返回衩侥。

需要注意的是:一般實現(xiàn)反射的話都是使用第三種方式Class.forName(“”).因為這個參數可以寫成變量傳進來,此時就可以讀取配置文件的字符串來動態(tài)的獲取相關類的字節(jié)碼實例矛物。

      /**
       * 獲取一個類的字節(jié)碼對象的三種方法 同一個類茫死,類實例(字節(jié)碼對象)在jvm中有且只有一份
       * 
       * @throws ClassNotFoundException
       */
      @Test
      public void test1() throws ClassNotFoundException {
          String str = "abc";
          // 表示返回此對象運行時類的 Class對象
          Class<? extends String> cls1 = str.getClass();
  
          // 編譯器通過String就可以確定返回String類型的Class對象。
          Class<String> cls2 = String.class;
  
          // 給編譯器看的履羞,編譯器并不知道通過forName會返回什么類型的Class對象
          Class<?> cls3 = Class.forName("java.lang.String");
  
          System.out.println(cls1 == cls2); // true
          System.out.println(cls1 == cls3); // true 
      }

由輸出結果可知峦萎,每個類不管使用三種方式中的哪種方式來獲取Class對象都是一份,從而證明了內存中同一個類的Class對象有且只有一份忆首。

9個預定義的class對象:八種基本數據類型和void關鍵字爱榔。

       /**
        * 預定義的Class對象
        */
       @Test
       public void test2() {
           Class<String> cls2 = String.class;
           // primitive是原始的意思,判定指定的 Class對象是否表示一個基本類型(原始類型)
           System.out.println(cls2.isPrimitive());
   
           // 判定指定的 Class 對象是否表示一個基本類型
           System.out.println(int.class.isPrimitive());
   
           // 基本類型和對應包裝類Class對象不是同一個
           System.out.println(int.class == Integer.class); //false int和Integer包裝類不是同一份字節(jié)碼
   
           /*
            * Integer.TYPE代表的是integer包裝的基本類的字節(jié)碼
            * 根據文檔:表示基本類型 int 的 Class 實例
            */
           System.out.println(int.class == Integer.TYPE);  //true
   
           //數組有對應的數組類(Array類)
           System.out.println(int[].class.isPrimitive()); //false
   
           // 是不是數組類class對象
           System.out.println(int[].class.isArray());
       }

2.反射的概念

JAVA反射機制是在運行狀態(tài)中糙及,對于任意一個類详幽,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性唇聘;這種動態(tài)獲取信息以及動態(tài)調用對象方法的功能稱為java語言的反射機制版姑。

JAVA反射(放射)機制:“程序運行時,允許改變程序結構或變量類型迟郎,這種語言稱為動態(tài)語言”剥险。從這個觀點看,Perl宪肖,Python表制,Ruby是動態(tài)語言,C++匈庭,Java夫凸,C#不是動態(tài)語言浑劳。但是JAVA有著一個非常突出的動態(tài)相關機制:Reflection阱持,用在Java身上指的是我們可以于運行時加載、探知魔熏、使用編譯期間完全未知的classes衷咽。換句話說,Java程序可以加載一個運行時才得知名稱的class蒜绽,獲悉其完整構造(但不包括methods定義)镶骗,并生成其對象實體、或對其fields設值躲雅、或喚起其methods.

Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類鼎姊;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法相赁;在運行時調用任意一個對象的方法相寇;生成動態(tài)代理。

反射就是把java類中的各個成分映射成相應的java類钮科。

例如:一個java類中用一個Class類的對象來表示唤衫,一個類中的組成部分:成員變量,方法绵脯,構造方法佳励,包等信息也用一個個的java類來表示,就像汽車是一個類蛆挫,汽車中的發(fā)動機赃承,變速箱等等也是一個個的類。表示java類的Class類顯然要提供一些方法來獲取其中的變量悴侵,方法楣导,構造方法,修飾符畜挨,包等信息筒繁,這些信息就是用相應類的實例對象來表示噩凹,他們是Filed,Method毡咏,Constructor驮宴,Package等等。(可以查看Class類的api就可以了解相關的方法)呕缭。

一個類的每個成員都可以用相應的反射API類的一個實例對象來表示堵泽,通過調用Class類的方法可以得到這些實例對象后,得到這些實例對象后有什么用呢恢总?怎么用呢迎罗?這才是要點。

反射在很多地方都能用到片仿,比如Spring(一個開放源代碼的設計層面框架)纹安,Struts(一個基于MVC設計模式的Web應用框架),JUnit(一個Java語言的單元測試框架)等一些框架中砂豌,反射是框架設計的靈魂厢岂。

3.構造方法的反射

Constructor類代表某個類中的一個構造方法。

       /**
        * 構造方法的反射
        * @throws NoSuchMethodException
        * @throws SecurityException
        * @throws InstantiationException
        * @throws IllegalAccessException
        * @throws IllegalArgumentException
        * @throws InvocationTargetException
        */
       @Test
       public void test3() throws NoSuchMethodException, SecurityException,
               InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException {
           Class<String> clazz = String.class;
           //獲取String類的所有構造方法
           Constructor<?>[] constructors = clazz.getConstructors();
   
           /*
            * 通過構造函數反射實例化對象
            */
           String str1 = new String(new StringBuffer("adc"));
           Constructor<String> constructor1 = String.class
                   .getConstructor(StringBuffer.class);
           String str2 = constructor1.newInstance(new StringBuffer("abc"));
   
           //使用默認的構造方法實例化對象阳距,newInstance
           String str3 = String.class.newInstance();
       }

使用newInstance方法來實例化對象的情況塔粒,newInstance方法先得到相應類的默認的構造方法,然后使用該默認的構造方法來實例化對象筐摘。
通過查看源碼知:java會用緩存機制來緩存默認的構造方法實例卒茬,由此可以看出用了緩存說明獲取Constructor對象是一個很耗時的操作。

擴展:因為反射機制的存在咖熟,所以單例模式并不能完全保證單例對象的唯一性圃酵。如何保證單例防反射攻擊,請看這篇: 單例模式--反射--防止序列化破壞單例模式

4.成員變量的反射

Filed類代表某個類中的一個成員變量球恤,即某個類的字節(jié)碼對象的字段對象辜昵,不和具體的類的實例對應。

  public class ReflectPoint {
      private Date birthday = new Date();
  
      private int x;
      public int y;
      public String str1;
      public String str2;
      public String str3;
  
      public ReflectPoint(int x, int y) {
          super();
          this.x = x;
          this.y = y;
      }
      
      public ReflectPoint(String str1, String str2, String str3) {
          super();
          this.str1 = str1;
          this.str2 = str2;
          this.str3 = str3;
      }
  
  
  
      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + x;
          result = prime * result + y;
          return result;
      }
  
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
              return true;
          if (obj == null)
              return false;
          if (getClass() != obj.getClass())
              return false;
          final ReflectPoint other = (ReflectPoint) obj;
          if (x != other.x)
              return false;
          if (y != other.y)
              return false;
          return true;
      }
  
      @Override
      public String toString() {
          return str1 + ":" + str2 + ":" + str3;
      }
  
      public int getX() {
          return x;
      }
  
      public void setX(int x) {
          this.x = x;
      }
  
      public int getY() {
          return y;
      }
  
      public void setY(int y) {
          this.y = y;
      }
  
      public Date getBirthday() {
          return birthday;
      }
  
      public void setBirthday(Date birthday) {
          this.birthday = birthday;
      }
  } 
      /**
       * 成員變量的反射
       * @throws SecurityException
       * @throws NoSuchFieldException
       * @throws IllegalAccessException
       * @throws IllegalArgumentException
       */
      @Test
      public void test4() throws NoSuchFieldException, SecurityException,
              IllegalArgumentException, IllegalAccessException {
          ReflectPoint pt1 = new ReflectPoint(3, 5);
          Class<? extends ReflectPoint> clazz = pt1.getClass();
          /*
           * 獲取指定的字段對象
           * fieldY的值是多少咽斧?是5,錯堪置!fieldY不是對象身上的變量,而是類上张惹,要用它去取某個對象上對應的值
           */
          Field fieldY = clazz.getField("y"); 
          
          //獲取pt1對象上的y字段的值
          System.out.println("變量Y的值:" + fieldY.getInt(pt1));
  
          /*
           * getField只能獲取public和defalut修飾的字段舀锨,此時x是私有變量。
           */
          /*
           * Field fieldX = clazz.getField("x");
           * System.out.println(fieldX.getInt(pt1));
           */
  
          /*
           * getDeclaredFields可以獲取類中所有的成員變量 包括私有的變量
           */
          Field[] fields = clazz.getDeclaredFields();
          System.out.println("成員變量個數:" + fields.length);
  
          /*
           * 獲取私有變量x的值
           * 雖然獲取到x了宛逗,但是沒有權限訪問其中的值坎匿,所以需要設置x字段對象為可以訪問的。
           */
          Field fieldX = clazz.getDeclaredField("x");
          fieldX.setAccessible(true);
          System.out.println("變量X的值:" + fieldX.getInt(pt1));
      }
      /**
       * 成員變量反射的綜合案例 將任意一個對象中的所有String類型的成員變量所對應的字段內容中的“b”改成”a”
       * @throws SecurityException
       * @throws NoSuchFieldException
       * @throws IllegalAccessException
       * @throws IllegalArgumentException
       */
      @Test
      public void test5() throws NoSuchFieldException, SecurityException,
              IllegalArgumentException, IllegalAccessException {
          ReflectPoint pt1 = new ReflectPoint("ball", "basketball", "itcast");
          System.out.println("修改前:");
          System.out.println(pt1.str1);
          System.out.println(pt1.str2);
          System.out.println(pt1.str3);
  
          Class<? extends ReflectPoint> clazz = pt1.getClass();
          // /Field fieldX = clazz.getDeclaredField("x");
          Field[] fields = clazz.getDeclaredFields();  //獲取所有的字段 包括私有字段
          for (Field field : fields) {
              /*
               * 獲取字段的類型(返回的是類型的字節(jié)碼實例) 判斷是否和String類的字節(jié)碼相等就能判斷是否是String類型的字段了。  
               * 因為字節(jié)碼只有一個,所以使用 == 比使用equeals更能體現(xiàn)意義
               */
              Class<?> filedType = field.getType();
              if (filedType == String.class) {
                  field.setAccessible(true);
                  String oldValue = (String) field.get(pt1);
                  String newValue = oldValue.replace("b", "a");
                  field.set(pt1, newValue);  //重新將替換后的新值set到相關到對象中去替蔬。
              }
           }
  
           System.out.println("修改后:");
           System.out.println(pt1.str1);
           System.out.println(pt1.str2);
           System.out.println(pt1.str3);
      }

結論:
從上可以看出對于一些對象告私,可以使用反射將其中的值都改掉,Spring實例化里邊的值和初始化對象的值都是如此實現(xiàn)的承桥。

5.成員方法的反射

Method類代表某個類中的一個成員方法驻粟。

      /**
       * 成員方法的反射
       * @throws SecurityException
       * @throws NoSuchMethodException
       * @throws InvocationTargetException
       * @throws IllegalArgumentException
       * @throws IllegalAccessException
       */
      @Test
      public void test6() throws NoSuchMethodException, SecurityException,
              IllegalAccessException, IllegalArgumentException,
              InvocationTargetException {
          String str = "abc";
          //獲取指定方法的Method類的實例
          Method method = String.class.getMethod("charAt", int.class);
          //調用指定實例的方法,并傳參
          //如果是Method代表的是靜態(tài)方法凶异,那么第一參數為null
          System.out.println(method.invoke(str, 1));
      }

6.對接收數組參數的成員方法進行反射

問題:
用反射的方式執(zhí)行某個類中的main方法,寫一個程序蜀撑,根據用戶提供的類名,去執(zhí)行該類的main方法剩彬。如果使用傳統(tǒng)的方式執(zhí)行main方法可以直接Test.main(new String[]{}); 但是不能動態(tài)指定類名(用戶提供的)酷麦,因為傳統(tǒng)的方式都已經編譯了不能再改了。

      /**
       * 對接收數組參數的成員方法進行反射 用反射的方式執(zhí)行某個類中的main方法,寫一個程序喉恋,根據用戶提供的類名沃饶,去執(zhí)行該類的main方法。
       * 
       * @throws ClassNotFoundException
       * @throws SecurityException
       * @throws NoSuchMethodException
       * @throws InvocationTargetException
       * @throws IllegalArgumentException
       * @throws IllegalAccessException
       */
      @Test
      public void test7() throws ClassNotFoundException, NoSuchMethodException,
              SecurityException, IllegalAccessException,
              IllegalArgumentException, InvocationTargetException {
  
          String mainStr = "mytest.TestArguments";
          Method mainMethod = Class.forName(mainStr).getMethod("main",
                  String[].class);
          mainMethod.invoke(null, new String[] { "a", "b", "c" }); 
      }
  /**
   * 測試反射main方法的類
   */
  class TestArguments {
      public static void main(String[] args) {
          for (String arg : args) {
              System.out.println(arg);
          }
      }
  }

上述代碼報錯:java.lang.IllegalArgumentException: wrong number of arguments

明顯是參數個數錯誤瀑晒,main方法確實需要一個參數绍坝,而我也傳了一個參數徘意,為什么會錯呢苔悦?

因為在為invoke傳遞數組類型的參數的時候,按照jdk1.5的做法椎咧,整個數組是一個參數玖详,而按照jdk1.4的語法,會將數組拆開勤讽,每個元素對應一個參數蟋座,所以當把一個字符串數組作為一個參數傳遞給invoke方法時,javac會按照哪種方法進行處理呢脚牍?jdk1.5肯定要兼容jdk1.4的做法向臀,會先按照1.4的語法處理,即把數組拆開為每一個元素作為一個參數诸狭。所以如果按照上邊的方式會出現(xiàn)異常券膀。可以采用下邊的方式:

      /**
       * 對接收數組參數的成員方法進行反射 用反射的方式執(zhí)行某個類中的main方法,寫一個程序驯遇,根據用戶提供的類名芹彬,去執(zhí)行該類的main方法。
       * @throws ClassNotFoundException
       * @throws SecurityException
       * @throws NoSuchMethodException
       * @throws InvocationTargetException
       * @throws IllegalArgumentException
       * @throws IllegalAccessException
       */
      @Test
      public void test7() throws ClassNotFoundException, NoSuchMethodException,
              SecurityException, IllegalAccessException,
              IllegalArgumentException, InvocationTargetException {
  
          String mainStr2 = "mytest.TestArguments";
          Method mainMethod2 = Class.forName(mainStr2).getMethod("main",
                  String[].class);
  
          /*
           *  jdk1.4的做法
           *  重新包裝字符串數組為一個object數組叉庐,此時按照1.4的方式拆開之后只有一個參數就是里邊的string數組
           */
          mainMethod2
                  .invoke(null, new Object[] { new String[] { "a", "b", "c" } });
  
          /*
           * jdk1.5的做法
           * 重新包裝字符串數組為一個object舒帮,此時給invoke方法傳遞的參數不是數組,編譯器不會去拆解了,
           * (數組也是Object)
           */
          mainMethod2.invoke(null, (Object) new String[] { "a", "b", "c" });
      }

7.數組與Object的關系及數組的反射類型

根據文檔中class的解釋玩郊,對于數組的Class對象實例肢执,具有相同維數(一維數組二維數組等)和元素類型的屬于同一個類型,即具有相同的Class實例對象译红。中文文檔的說明:所有具有相同元素類型和維數的數組都共享該 Class 對象蔚万。

     int[] a1 = new int[] { 1, 2, 3 };
     Integer[] a11 = new Integer[] { 1, 2, 3 };
     int[] a2 = new int[4];
     int[][] a3 = new int[2][3];
     String[] a4 = new String[] { "a", "b", "c" };
    
     System.out.println(a1.getClass() == a2.getClass()); // true

     // 都是一維數組,但是數組元素類型不一致临庇,直接編譯不通過反璃。
     // System.out.println(a1.getClass() == a4.getClass());
     // 數組元素類型以致,但是維數不同假夺,直接編譯不通過淮蜈。
     // System.out.println(a1.getClass() == a3.getClass());

數組的反射類型的name:

         /*
         * 基本類型的數組getName
         */
        //[I
        System.out.println("int[]:" + a1.getClass().getName());
        //int
        System.out.println("int:" + int.class.getName());

        /*
         * 引用類型的數組getName
         */
        // [Ljava.lang.String;
        System.out.println("String[]:" + a4.getClass().getName());
        // java.lang.String
        System.out.println("String:" + String.class.getName());

        /*
         * 與getName相對應的是forName 
         * 根據數組類型的Name類獲取Class
         */
        // 基本類型
        Class<?> c1 = Class.forName("[I");
        System.out.println(c1.isArray()); // true

        // 引用類型
        Class<?> c2 = Class.forName("[Ljava.lang.String;");
        System.out.println(c2.isArray()); // true

對于"[I"中,[表示數組已卷,I表示數組元素類型是int梧田。
具體I代表什么參考getName方法的api注釋:

基礎類型:
Element Type  Encoding 
boolean        Z  
byte           B  
char           C   
double         D  
float          F  
int            I  
long           J  
short          S 

引用類型:
Element Type             Encoding
class or interface       Lclassname;  

例子: 
 String.class.getName()
 returns "java.lang.String"

 byte.class.getName()
 returns "byte"

 (new Object[3]).getClass().getName()
 returns "[Ljava.lang.Object;"

 (new int[3][4][5][6][7][8][9]).getClass().getName()
 returns "[[[[[[[I"

getSimpleName方法

  // String
  System.out.println(String.class.getSimpleName());

  // int[]
  System.out.println(a1.getClass().getSimpleName()); 

8.數組的反射應用

數組不是類,但是實現(xiàn)了Object中的方法侧蘸。

按照Java語言規(guī)范的說法裁眯,Java數據類型分為兩大類:基本數據類型和復合數據類型,其中復合數據類型包括數組讳癌、類和接口穿稳。

Array類(Array工具類)完成對數組的反射,是代表了對于數組類的描述晌坤。文檔中說明:Array 類提供了動態(tài)創(chuàng)建和訪問 Java 數組的方法逢艘。

擴展 : java.lang.reflect包

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市骤菠,隨后出現(xiàn)的幾起案子它改,更是在濱河造成了極大的恐慌,老刑警劉巖商乎,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件央拖,死亡現(xiàn)場離奇詭異,居然都是意外死亡鹉戚,警方通過查閱死者的電腦和手機鲜戒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崩瓤,“玉大人袍啡,你說我怎么就攤上這事∪赐埃” “怎么了境输?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵蔗牡,是天一觀的道長。 經常有香客問我嗅剖,道長辩越,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任信粮,我火速辦了婚禮黔攒,結果婚禮上,老公的妹妹穿的比我還像新娘强缘。我一直安慰自己督惰,他們只是感情好,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布旅掂。 她就那樣靜靜地躺著赏胚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪商虐。 梳的紋絲不亂的頭發(fā)上觉阅,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機與錄音秘车,去河邊找鬼典勇。 笑死,一個胖子當著我的面吹牛叮趴,可吹牛的內容都是我干的割笙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼疫向,長吁一口氣:“原來是場噩夢啊……” “哼咳蔚!你這毒婦竟也來了豪嚎?” 一聲冷哼從身側響起搔驼,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侈询,沒想到半個月后舌涨,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡扔字,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年囊嘉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片革为。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡扭粱,死狀恐怖,靈堂內的尸體忽然破棺而出震檩,到底是詐尸還是另有隱情琢蛤,我是刑警寧澤蜓堕,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站博其,受9級特大地震影響套才,放射性物質發(fā)生泄漏。R本人自食惡果不足惜慕淡,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一背伴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧峰髓,春花似錦傻寂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至眉孩,卻和暖如春个绍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浪汪。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工巴柿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人死遭。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓广恢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呀潭。 傳聞我的和親對象是個殘疾皇子钉迷,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內容

  • 寫在前面的話:很多人會說我直接new一個對象不就完了么,干嘛還用反射來獲取對象钠署。因為new屬于靜態(tài)編譯糠聪,而反射屬于...
    iDaniel閱讀 8,615評論 1 4
  • 前言 Java反射機制很早的時候就有耳聞,期間也會去看看相關資料谐鼎,但是又很快會忘記舰蟆,所以,寫一篇Blog來加深記憶...
    Android_Simon閱讀 515評論 0 1
  • 活著就像個鐘擺一會兒撞到無聊狸棍,一會兒又被無聊彈回去哐當撞到痛苦一邊身害,來回在無聊與痛苦之間擺動,我時不常有輕生厭世的...
    單立人道長閱讀 247評論 0 0
  • 自主招生又稱自主選拔草戈,主要選拔具有學科特長和創(chuàng)新潛質的優(yōu)秀學生塌鸯。是對現(xiàn)行統(tǒng)一高考招生按分數錄取的一種補充,同時也是...
    咚咕隆咚閱讀 246評論 0 0
  • 昨天承認了自己是個偽學習者以后丢习,好像如釋重負,面對真實地自己淮悼。似乎看清楚真實地自己才知道自己應該需要怎么做這件事咐低。...
    一個景天閱讀 421評論 0 1