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

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

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

    lqxue

    常用鏈接

    統計

    book

    tools

    最新評論

    【轉】JAVA的內省(introspector)與反射(reflection)

     很多朋友在深入的接觸 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());

    上面的兩個例子是比較常用方法。看到上面的例子就有人要發問了:為什么要這么麻煩呢?本來一條語句就完成的事情干嗎要整這么復雜?沒錯,在上面的例子中確實沒有必要這么麻煩。不過你想像這樣一個應用程序,它支持動態的功能擴展,也就是說程序不重新啟動但是可以自動加載新的功能,這個功能使用一個具體類來表示。首先我們必須為這些功能定義一個接口類,然后我們要求所有擴展的功能類必須實現我指定的接口,這個規定了應用程序和可擴展功能之間的接口規則,但是怎么動態加載呢?我們必須讓應用程序知道要擴展的功能類的類名,比如是 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 項目,其實應該說幾乎所有的項目都或多或少的采用這兩種技術。在實際應用過程中二者要相互結合方能發揮真正的智能化以及高度可擴展性。

    另外,以下是SUN的java doc 對Introspector的解釋:
    public class Introspector
    extends Object

    The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.

    For each of those three kinds of information, the Introspector will separately analyze the bean's class and superclasses looking for either explicit or implicit information and use that information to build a BeanInfo object that comprehensively describes the target bean.

    For each class "Foo", explicit information may be available if there exists a corresponding "FooBeanInfo" class that provides a non-null value when queried for the information. We first look for the BeanInfo class by taking the full package-qualified name of the target bean class and appending "BeanInfo" to form a new class name. If this fails, then we take the final classname component of this name, and look for that class in each of the packages specified in the BeanInfo package search path.

    Thus for a class such as "sun.xyz.OurButton" we would first look for a BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd look in each package in the BeanInfo search path for an OurButtonBeanInfo class. With the default search path, this would mean looking for "sun.beans.infos.OurButtonBeanInfo".

    If a class provides explicit BeanInfo about itself then we add that to the BeanInfo information we obtained from analyzing any derived classes, but we regard the explicit information as being definitive for the current class and its base classes, and do not proceed any further up the superclass chain.

    If we don't find explicit BeanInfo on a class, we use low-level reflection to study the methods of the class and apply standard design patterns to identify property accessors, event sources, or public methods. We then proceed to analyze the class's superclass and add in the information from it (and possibly on up the superclass chain).

    Because the Introspector caches BeanInfo classes for better performance, take care if you use it in an application that uses multiple class loaders. In general, when you destroy a ClassLoader that has been used to introspect classes, you should use the Introspector.flushCaches or Introspector.flushFromCaches method to flush all of the introspected classes out of the cache.

    For more information about introspection and design patterns, please consult the JavaBeans specification.

    posted on 2008-07-14 17:21 lqx 閱讀(372) 評論(0)  編輯  收藏 所屬分類: java

    主站蜘蛛池模板: 在线a亚洲v天堂网2019无码| 99久久免费精品高清特色大片| 皇色在线免费视频| 成在人线av无码免费高潮喷水| 在线日韩av永久免费观看| 亚洲欧洲自拍拍偷综合| 中文字幕乱理片免费完整的| 又粗又黄又猛又爽大片免费 | 亚洲婷婷在线视频| 国产精品偷伦视频观看免费| 亚洲天堂在线视频| 爱情岛亚洲论坛在线观看| 日韩毛片免费无码无毒视频观看| 亚洲国产视频一区| 18禁成人网站免费观看| 一区二区三区亚洲| 久久久久国产精品免费网站| 亚洲免费观看视频| 花蝴蝶免费视频在线观看高清版| 亚洲日韩涩涩成人午夜私人影院| 国产偷国产偷亚洲高清在线| 一二三四免费观看在线视频中文版 | 国产亚洲精品VA片在线播放| 69影院毛片免费观看视频在线| 精品日韩亚洲AV无码一区二区三区 | 亚洲视频在线不卡| 免费高清小黄站在线观看| 爱情岛论坛亚洲品质自拍视频网站 | 精品国产亚洲一区二区三区在线观看 | 国产午夜亚洲精品不卡| 亚洲成色在线综合网站| 亚洲人成免费电影| 午夜亚洲国产精品福利| 亚洲精品无码成人片久久| 在线看片v免费观看视频777| 日日摸日日碰夜夜爽亚洲| 亚洲av永久无码精品网站| 免费黄色大片网站| 久久精品成人免费看| 亚洲午夜无码久久久久小说 | 亚洲免费无码在线|