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

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

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

    很久很久以前

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      34 隨筆 :: 4 文章 :: 17 評論 :: 0 Trackbacks
    原文地址:http://www.eclipsezone.com/articles/what-is-iadaptable/

    IAdaptable在Eclipse里是一個非常重要的接口。對于Eclipse開發老手來說,它就像異常處理和抽象類一樣尋常;但是對新手而言,它卻令人感到困惑和畏懼。這篇文章將向你解釋IAdaptable到底是什么,以及它在Eclipse里起到的作用。

    類型轉換
    Java是所謂的強類型語言,也就是說,每個實例都對應一個類型。其實類型分為兩種:聲明類型和運行時類型(也分別被稱為靜態類型和動態類型)。像Python這樣的弱類型語言常被稱為無類型的語言,其實嚴格說來不是這樣,因為每個實例都對應一個運行時類型,只是你并不需要聲明這一點而已。

    現在回到Java,為了能夠執行一個類的某個方法,這個方法必須在聲明類型中可見,換句話說,即使在運行時實例是某個子類型,你也只能執行那些父類型里定義的方法。


    List list = new ArrayList(); 
    list.add("data");       // 正確,add是List里定義的方法 
    list.ensureCapacity(4); // 不正確,ensureCapacity()只在ArrayList被定義 
     
    如果一定要執行特定類型的方法,我們必須先強制轉換這個實例到正確的類型。對于上面的例子,我們可以將list轉換為ArrayList(譯注:原文In this case, we can cast ArrayList to List,懷疑是筆誤),因為ArrayList實現了List接口,你甚至可以在運行時通過instanceof關鍵字檢驗list是否為ArrayList的一個實例。

    可擴展的接口
    不幸的是,一個類可能并沒有實現你需要的接口,這樣就無法進行強制類型轉換了。原因有很多,比如只在少數情況下才需要這個接口,或者你需要的接口是在另一個不相關的庫里,又或者接口是有了類以后才開發出來的,等等。

    這時你就需要IAdaptable了??梢园袸Adaptable想象為一個能夠動態進行類型轉換的途徑。對比下面的直接類型轉換:


    Object o = new ArrayList(); 
    List list = (List)o; 
     
    換一種方式,我們可以這樣做:


    IAdaptable adaptable = new ArrayList();//譯注:這里的ArrayList應該不是指java.util.ArrayList 
    List list = (List)adaptable.getAdapter(java.util.List.class); 
     
    這就是上面所說的動態類型轉換,我們所做的事情是試圖把adaptable轉換為一個List實例。

    那么,當可以直接轉換的時候為什么要費這個力氣通過getAdapter()來轉換呢?其實這種機制可以讓我們將目標類轉換為它并沒有實現的接口。舉個例子,我們可能想把一個HashMap當作List來用,盡管這兩個類的性質并不相同,可以這么做:


    IAdaptable adaptable = new HashMap();//譯注:這里的HashMap應該不是指java.util.HashMap 
    List list = (List)adaptable.getAdapter(java.util.List.class); 
     
    實現IAdaptable接口
    大部分IAdaptable的實現是一些if語句的疊加,比如我們現在要實現HashMap的getAdapter()方法,它看起來可能是這樣:


    public class HashMap implements IAdaptable { 
      public Object getAdapter(Class clazz) { 
        if (clazz == java.util.List.class) { 
          List list = new ArrayList(this.size()); 
          list.addAll(this.values()); 
          return list; 
        } 
        return null; 
      } 
      //  

     
    所做的就是返回一個適配器(adapter,更確切的說是一個副本),而不是進行直接的類型轉換。如果參數類型沒有被支持,慣例是返回null值(而非拋出異常),代表這個方法失敗了。因此,在調用這個方法時,不應該假定它總是返回非null值。

    PlatformObject
    當然,如果你希望增加一個新的被支持的adapter類型時必須編輯這個類才行(譯注:在getAdapter()里增加更多的if語句),這會比較辛苦。而且,既然你已經知道了這個類型,何不直接修改接口聲明呢?其實有很多原因使得你并不希望直接編輯這個類(例如更容易保持向下兼容性),也不想改變它的類型(HashMap雖然不是一個List,但可以轉換過去)。

    Eclipse通過PlatformObject抽象類來解決以上問題,它為你實現了IAdaptable接口,Eclipse平臺(Platform)提供了IAdapterManager的一個實現,并且可以通過Platform.getAdapterManager()訪問到,它把所有對getAdapter()的請求(調用)委托給一個名為IAdapterManager的東西。你可以將它想象為一個巨大的保存著類和adapter信息的Map,而PlatformObject的getAdapter()方法會查找這個Map。

    適配已存在的類
    這樣,PlatformObject不需要重新編譯就能夠支持新的adapter類型,這一點在Eclipse里被大量使用以支持workspace的擴展點。

    現在假設我們想要將一個只包含String類型元素的List轉換為一個XMl節點,這個節點的格式如下:


    <List> 
      <Entry>First String</Entry> 
      <Entry>Second String</Entry> 
      <Entry>Third String</Entry> 
    </List> 
     
    因為toString()方法可能有其他用途,我們不能通過覆蓋toString()方法來實現這個功能。所以,我們要給List關聯一個工廠類以處理XML節點類型的適配請求。要管理工廠類需要以下三個步驟:

    1、由List生成一個Node,我們把這個轉換過程用IAdapterFactory包裝起來:


    import nu.xom.*; 
    public class NodeListFactory implements IAdapterFactory { 
      /**//* 可以轉換到的類型 */ 
      private static final Class[] types = { 
        Node.class, 
      }; 
      public Class[] getAdapterList() { 
        return types; 
      } 
      /**//* 轉換到Node的功能代碼 */ 
      public Object getAdapter(Object list, Class clazz) { 
        if (clazz == Node.class && list instanceof List) { 
          Element root = new Element("List"); 
          Iterator it = list.iterator(); 
          while(it.hasNext()) { 
            Element item = new Element("Entry"); 
            item.appendChild(it.next().toString()); 
            root.appendChild(item); 
          } 
          return root; 
        } else { 
          return null; 
        } 
      } 

     
    2、把這個工廠類注冊到Platform的AdapterManager,這樣當我們希望從List的實例中獲得一個Node實例時,就會找到我們的工廠類。注冊一個工廠類的方式也很簡單:


    Platform.getAdapterManager().registerAdapters( 
      new NodeListFactory(), List.class 
    ); 
     
    這條語句將NodeListFactory關聯到List類型。當從List里請求adapter時,Platform的AdapterManager會找到NodeListFactory,因為在后者的getAdapterList()方法的返回結果里包含了Node類,所以它知道從List實例得到一個Node實例是可行的。在Eclipse里,這個注冊步驟一般是在plugin啟動時完成的,但也可以通過org.eclipse.core.runtime.adapters擴展點來完成。

    3、從List獲得Node,下面是例子代碼:


    Node getNodeFrom(IAdaptable list) { 
      Object adaptable = list.getAdapter(Node.class); 
      if (adaptable != null) { 
        Node node = (Node)adaptable; 
        return node; 
      } 
      return null; 

     
    總結
    綜上所述,要在運行時為一個已有的類增加功能,所要做的只是定義一個用來轉換的工廠類,然后把它注冊到Platform的AdapterManager即可。這種方式在保持UI組件和非UI組件的分離方面特別有用。例如在org.rcpapps.rcpnews.ui和org.rcpapps.rcpnews這兩個plugin里,前者的IPropertySource需要與后者的數據對象(data object)相關聯,當前者初始化時,它將IPropertySource注冊到Platform,當數據對象在導航器(navigator)里被選中的時候,屬性視圖里就會顯示正確的屬性。

    顯然,java.util.List并不是PlatformObject的子類,所以如果你希望能夠編譯這里所說的例子,必須建立一個List的子類型。注意,可以直接實現IAdaptable接口,而非必須繼承PlatformObject抽象類。


    public class AdaptableList implements IAdaptable, List { 
      public Object getAdapter(Class adapter) { 
         return Platform.getAdapterManager().getAdapter(this, adapter); 
      } 
      private List delegate = new ArrayList(); 
      public int size() { 
        return delegate.size(); 
      } 
      //  

     
    最后,例子里生成XML的部分使用了XOM的類庫.
    posted on 2006-02-18 15:36 Long Long Ago 閱讀(210) 評論(0)  編輯  收藏

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


    網站導航:
     
    主站蜘蛛池模板: 无码人妻精品中文字幕免费| 一级毛片在播放免费| 67194国产精品免费观看| 亚洲第一AAAAA片| www永久免费视频| 亚洲毛片网址在线观看中文字幕 | 69xx免费观看视频| 亚洲精品视频在线免费| 日韩精品免费一级视频| 亚洲人成网站在线观看播放动漫 | 亚洲精品在线不卡| 国产91免费视频| 亚洲人精品亚洲人成在线| 好吊妞788免费视频播放| 亚洲人成色99999在线观看| 国产传媒在线观看视频免费观看 | 麻豆精品成人免费国产片| 久久精品国产亚洲77777| 精品福利一区二区三区免费视频| 自拍日韩亚洲一区在线| 日韩中文字幕免费| 一级毛片高清免费播放| 亚洲一区综合在线播放| 国产卡二卡三卡四卡免费网址| 亚洲国产欧美一区二区三区| 伊在人亚洲香蕉精品区麻豆| 天黑黑影院在线观看视频高清免费| 99ri精品国产亚洲| 日韩a级毛片免费观看| 国产成人1024精品免费| 亚洲色成人网一二三区| 免费黄色小视频网站| 国产免费MV大全视频网站 | 亚洲人成电影青青在线播放| 日本免费人成黄页在线观看视频| 一本一道dvd在线观看免费视频| 亚洲bt加勒比一区二区| 日韩成人免费视频播放| 色www永久免费| 亚洲熟妇AV一区二区三区宅男| 在线观看国产区亚洲一区成人|