<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    licheng700

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      26 Posts :: 5 Stories :: 5 Comments :: 1 Trackbacks

    很多朋友在深入的接觸JAVA語言后就會發現這樣兩個詞:反射(Reflection)和內省(Introspector),經常搞不清楚這到底是怎么回事,在什么場合下應用以及如何使用?今天把這二者放在一起介紹,因為它們二者是相輔相成的。

    反射

    相對而言,反射比內省更容易理解一點。用一句比較白的話來概括,反射就是讓你可以通過名稱來得到對象(類,屬性,方法)的技術。例如我們可以通過類名來生成一個類的實例;知道了方法名,就可以調用這個方法;知道了屬性名就可以訪問這個屬性的值。

    還是寫兩個例子讓大家更直觀的了解反射的使用方法:

    //通過類名來構造一個類的實例
    Class cls_str = Class.forName("java.lang.String");
    //上面這句很眼熟,因為使用過JDBC訪問數據庫的人都用過J
    Object str = cls_str.newInstance();
    //相當于 String str = new String();

    //通過方法名來調用一個方法
    String methodName = "length";
    Method m = cls_str.getMethod(methodName,null);
    System.out.println("length is " + m.invoke(str,null));
    //相當于System.out.println(str.length());

    上面的兩個例子是比較常用方法??吹缴厦娴睦泳陀腥艘l問了:為什么要這么麻煩呢?本來一條語句就完成的事情干嗎要整這么復雜?沒錯,在上面的例子中確實沒有必要這么麻煩。不過你想像這樣一個應用程序,它支持動態的功能擴展,也就是說程序不重新啟動但是可以自動加載新的功能,這個功能使用一個具體類來表示。首先我們必須為這些功能定義一個接口類,然后我們要求所有擴展的功能類必須實現我指定的接口,這個規定了應用程序和可擴展功能之間的接口規則,但是怎么動態加載呢?我們必須讓應用程序知道要擴展的功能類的類名,比如是test.Func1,當我們把這個類名(字符串)告訴應用程序后,它就可以使用我們第一個例子的方法來加載并啟用新的功能。這就是類的反射,請問你有別的選擇嗎?

           關于方法的反射建議大家看我的另外一篇文章《利用Turbine的事件映射來擴展Struts的功能》,地址是:http://www.javayou.com/article/CSDN/extend_struts.html。這篇文章詳細介紹了如果通過反射來擴展Struts框架的功能。

    內省

    內省是Java語言對Bean類屬性、事件的一種缺省處理方法。例如類A中有屬性name,那我們可以通過getName,setName來得到其值或者設置新的值。通過getName/setName來訪問name屬性,這就是默認的規則。Java中提供了一套API用來訪問某個屬性的getter/setter方法,通過這些API可以使你不需要了解這個規則(但你最好還是要搞清楚),這些API存放于包java.beans中。

    一般的做法是通過類Introspector來獲取某個對象的BeanInfo信息,然后通過BeanInfo來獲取屬性的描述器(PropertyDescriptor),通過這個屬性描述器就可以獲取某個屬性對應的getter/setter方法,然后我們就可以通過反射機制來調用這些方法。下面我們來看一個例子,這個例子把某個對象的所有屬性名稱和值都打印出來:

    /* 
     * Created on 2004-6-29
     */

    package demo;

    import java.beans.BeanInfo;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;

    /**
     * 內省演示例子
     * @author liudong
     */

    public class IntrospectorDemo {
        String name;
        public static void main(String[] args) throws Exception{
            IntrospectorDemo demo = new IntrospectorDemo();
            demo.setName("Winter Lau");       

            //如果不想把父類的屬性也列出來的話,
            //getBeanInfo的第二個參數填寫父類的信息
            BeanInfo bi = Introspector.getBeanInfo(demo.getClass(),Object.class);
            PropertyDescriptor[] props = bi.getPropertyDescriptors();
            for(int i=0;i<props.length;i++){
                System.out.println(props[i].getName()+"="+
                        props[i].getReadMethod().invoke(demo,null));
            }

        }   

        public String getName() {
            return name;
        }

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

    Web開發框架Struts中的FormBean就是通過內省機制來將表單中的數據映射到類的屬性上,因此要求FormBean的每個屬性要有getter/setter方法。但也并不總是這樣,什么意思呢?就是說對一個Bean類來講,我可以沒有屬性,但是只要有getter/setter方法中的其中一個,那么Java的內省機制就會認為存在一個屬性,比如類中有方法setMobile,那么就認為存在一個mobile的屬性,這樣可以方便我們把Bean類通過一個接口來定義而不用去關系具體實現,不用去關系Bean中數據的存儲。比如我們可以把所有的getter/setter方法放到接口里定義,但是真正數據的存取則是在具體類中去實現,這樣可提高系統的擴展性。

    總結

    Java的反射以及內省應用到程序設計中去可以大大的提供程序的智能化和可擴展性。有很多項目都是采取這兩種技術來實現其核心功能,例如我們前面提到的Struts,還有用于處理XML文件的Digester項目,其實應該說幾乎所有的項目都或多或少的采用這兩種技術。在實際應用過程中二者要相互結合方能發揮真正的智能化以及高度可擴展性。

    posted on 2005-08-15 08:39 小海船 閱讀(229) 評論(0)  編輯  收藏

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


    網站導航:
     
    主站蜘蛛池模板: 婷婷亚洲综合五月天小说在线| 两个人看的www免费视频| 夜色阁亚洲一区二区三区| 国产va免费精品| 亚洲第一香蕉视频| 国产在线98福利播放视频免费| 国产精品午夜免费观看网站| 亚洲最大中文字幕| 日韩精品电影一区亚洲| 131美女爱做免费毛片| 最好2018中文免费视频| 亚洲一二成人精品区| 日本免费福利视频| 日韩精品极品视频在线观看免费| 亚洲精品亚洲人成在线| 亚洲产国偷V产偷V自拍色戒| 热99re久久免费视精品频软件| 中文字幕免费不卡二区| 亚洲爆乳无码精品AAA片蜜桃| 亚洲AV午夜福利精品一区二区| 特级淫片国产免费高清视频| 精品一区二区三区免费毛片爱| 羞羞漫画页面免费入口欢迎你| 亚洲精品电影天堂网| 亚洲自偷自偷偷色无码中文| 精品久久免费视频| 亚洲电影免费观看| 两个人的视频www免费| 99亚洲男女激情在线观看| 中文字幕亚洲综合久久2| 久久精品国产精品亚洲人人| 最近免费中文字幕大全视频| 久久久久国色av免费看 | 中文成人久久久久影院免费观看| 亚洲入口无毒网址你懂的| 久久精品国产亚洲av四虎| 亚洲国产成人影院播放| 四虎免费在线观看| 国产卡一卡二卡三免费入口 | 亚洲精品高清一二区久久| 女人18毛片水真多免费看|