andy-j2ee  
          JAVA
          公告
          • 在夜深人靜的時候,偶彈起心愛的土琵琶,唱起那動人的歌謠(柯受良-《大哥》):偶寫了代碼好多年,偶不愛冰冷的床沿,不要逼偶想念,不要逼偶流淚,偶會翻。
          日歷
          <2011年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910
          統計
          • 隨筆 - 19
          • 文章 - 1
          • 評論 - 1
          • 引用 - 0

          導航

          常用鏈接

          留言簿

          隨筆分類(5)

          隨筆檔案(19)

          文章分類(1)

          文章檔案(1)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           
              以前一直只知道有reflect這么一個類是用來反射的,聽人家說java中的反射很難,晚上聽罷張老師講的反射這一節的內容,惶然大悟,原來反射就是把Java類中的各種成分映射成相應的java類。    
              反射的基礎是要掌握Class這個類的,具體Class的類是干什么的,下面是api文檔中的解釋
             
          api中關于Class類的一段描述
          Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
          翻譯成中文
          Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬于被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。基本的 Java 類型(booleanbytecharshortintlongfloatdouble)和關鍵字 void 也表示為 Class 對象。
              可以看出Class類就是一個類或者接口對象的一個實例在內存中的字節碼,而如何得到一個類的字節碼呢?其方法有三:
          1         Class<? extends String> cls1 = str1.getClass();
          2         Class<String> cls2 = String.class;
          3         Class<?> cls3 = Class.forName("java.lang.String");
              而Class的isPrimitive()方法就是用來判斷一個類的字節碼是不是9個預定義的class
              
              接下來是Constructor類,Constructor類代表某個類中的一個構造方法。
             得到某個類所有的構造方法: 例子
          Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
            
              得到某一個構造方法:
             例子:
          Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//獲得方法時要用到類型
           
              創建實例對象:
          //通常方式:
          String str = new String(new StringBuffer("abc"));
              
          //反射方式: 
          String str = (String)constructor.newInstance(new StringBuffer("abc"));//調用獲得的方法時要用到上面相同類型的實例對象
             
              Class.newInstance()方法:
             例子:
          String obj = (String)Class.forName("java.lang.String").newInstance();
              該方法內部先得到默認的構造方法,然后用該構造方法創建實例對象。
             該方法內部的具體代碼是怎樣寫的呢?用到了緩存機制來保存默認構造方法的實例對象。
             

          下面是一個Field反射的綜合實例
          將任意一個對象中的所有String類型的成員變量所對應的字符串內容中的"b"改成"a"。 
          首先定義一個ReflectPoint的類
           1 package com.anduo.day1;
           2 
           3 public class ReflectPoint {
           4     private int x;
           5     public int y;
           6     public String a = "ball";
           7     public String b = "basketball";
           8     public String c = "hello";
           9 
          10     public ReflectPoint(int x, int y) {
          11         super();
          12         this.x = x;
          13         this.y = y;
          14     }
          15 
          16     @Override
          17     public String toString() {
          18         return "a=" + a + ";b=" + b + ";c=" + c;
          19     }
          20 }
          21 

          下面的步驟是:先從對象中得到所有為String類型的字段,2:得到Sting字段的值;3:用String類的replace方法代換a字符為b字符;4:把對象的String字段設置為修改完的新String。
          齊活兒
           1 package com.anduo.day1;
           2 
           3 import java.lang.reflect.Constructor;
           4 import java.lang.reflect.Field;
           5 
           6 public class ReflectTest {
           7 
           8     
           9     public static void main(String[] args) throws Exception {
          10 
          11         
          12         /**
          13          * 成員變量的反射 Field
          14          */
          15         System.out.println("**成員變量的反射 Field**");
          16         ReflectPoint pt1 = new ReflectPoint(1-1);
          17         Field fieldY = pt1.getClass().getField("y");
          18         // fieldY 不是對象身上的變量,而是類上,要用它來去對象上字段的值
          19         System.out.println("p1 中  y = " + fieldY.get(pt1));
          20         Field fieldX = pt1.getClass().getDeclaredField("x");// 獲取私有屬性字段
          21         fieldX.setAccessible(true);// 暴力反射
          22         System.out.println("p1 中  x = " + fieldX.get(pt1));
          23 
          24         /**
          25          * 將任意一個對象中的所有String類型的成員變量所對應的字符串內容中的"b"改成"a"
          26          */
          27         changeStringValue(pt1);
          28         System.out.println(pt1);
          29     }
          30 
          31     /**
          32      * 將任意一個對象中的所有String類型的成員變量所對應的字符串內容中的"b"改成"a"
          33      * @param obj
          34      * @throws IllegalArgumentException
          35      * @throws IllegalAccessException
          36      */
          37     private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
          38         Field[] fields = obj.getClass().getFields();
          39         for (Field field : fields) {
          40             // if(field.getType().equals(String.class))
          41             if (field.getType() == String.class) {
          42                 String oldValue = (String) field.get(obj);
          43                 String newValue = oldValue.replace('a''b');
          44                 field.set(obj, newValue);
          45             }
          46         }
          47     }
          48 
          49 }
          50 
          結果如下
          **成員變量的反射 Field**
          p1 中  y 
          = -1
          p1 中  x 
          = 1
          a
          =bbll;b=bbsketbbll;c=hello

          綜上可以看出,其實反射也沒多難,人家那些寫框架的也不就是用了些反射嗎?把配置文件中的東西讀出來,然后再調用下面的類去做應該做的事情,當然這個過程就用到了反射了。

          posted on 2011-11-07 20:58 安多 閱讀(323) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
           
          Copyright © 安多 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 铅山县| 康马县| 邹城市| 石林| 黑河市| 含山县| 湟源县| 双桥区| 观塘区| 苍梧县| 永平县| 阳山县| 玛纳斯县| 玉树县| 鹤峰县| 浏阳市| 大埔县| 新化县| 桃源县| 广水市| 阳西县| 宁津县| 自治县| 巴楚县| 会泽县| 得荣县| 绥江县| 宣城市| 常山县| 蕉岭县| 北宁市| 安西县| 来宾市| 武强县| 仲巴县| 朝阳区| 泰州市| 邵阳县| 丹凤县| 郯城县| 横峰县|