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

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

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

    如鵬網 大學生計算機學習社區

    CowNew開源團隊

    http://www.cownew.com 郵件請聯系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

    類型轉化

    Java是一種強類型語言,每個實例都必須有指定的類型。實際上,Java類型有兩種聲明類型運行時類型 (也可以相應的說是靜態類型動態類型 ). 像Python這樣的弱類型語言通常稱為無類型,但是這樣說并不嚴謹,因為每個實例都有它的運行時類型。你只是不用事先聲明一個實例的類型而已。

    要想調用一個對象中的方法,這個方法需要在聲明類型中存在。也就是說,你只能調用定義在父類中的方法,即使該實例是一個確定的子類型:

    List list = new ArrayList();
    list.add("data");       // 在這里沒問題
    list.ensureCapacity(4); // 這里就不行了ensureCapacity() 只在ArrayList中才有。
    

    如果我們要調用實際類型中的方法,我們首先要將它轉為正確的類型。在本例中,我們可以把 ArrayList 轉為List,因為ArrayList實現了List 接口. 也可以在運行時動態的檢驗,使用 list instanceof ArrayList.

    可擴展的接口

    糟糕的是,一個類不能總是實現你所需要實現的接口。可能是因為這只對少數幾種情況才有效,或者它是一個沒有被關聯的庫中的類型,或者這個接口在后期又被改變了。

    這種情況就可以使用IAdaptable。 你可以把 IAdaptable 動態的進行類型轉化。使用如下方法避免直接的類型轉化:

    Object o = new ArrayList();
    List list = (List)o;
    

    我們可以這樣做:

    IAdaptable adaptable = new ArrayList();
    List list = (List)adaptable.getAdapter(java.util.List.class);
    

    你可認為它是一種類型動態轉化; 我們把adaptable轉為List實例。

    為什么不直接轉化,而要用額外的getAdapter() 呢?這種機制可以使我們將目標類轉化為沒有實現的接口。例如, 我們可能想使用HashMap 作為一個 List, 盡管他們并不兼容。

    IAdaptable adaptable = new 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;
      }
      // ...
    }
    

    返回的是一個對自身的代理,而不是直接轉化類型。如果請求的是不支持的類型,可以直接返回null表明失敗,這樣比拋出異常要好。

    PlatformObject

    當你想添加新的要擴展的類型時,只是簡單的修改一下就可以了。在任何情況下,如果已經得到了類型,為什么不修改接口?不修改類(如果使用接口,不容易保證向后兼容)或者改變它的類型(HashMap不是 List,但是可以轉化)是有原因的。要解決這個問題,在Eclipse中,使用了一個抽象類 HashMap is not a List, but can be conveted into one).

    To solve this problem, there's an abstract class that is used by most parts of Eclipse called -->PlatformObject。它為你實現了 IAdaptable接口,你就可以不用再操心了。

    PlatformObject 代理所有的它對getAdapter()的請求到 IAdapterManager. IAdapterManager是平臺默認提供的,通過 Platform.getAdapterManager()來訪問。你可以將它想象為一個巨大的 Map ,它負責關聯類和適當的適配器。PlatformObjectgetAdapter() 方法可以訪問到這個Map.

    適配已存在的類

    這樣的好處是可以為每一個PlatformObject對象動態的關聯新的適配器,而不用重新編譯。在Eclipse中的很多地方都是這樣來支持擴展的。

    這里希望將裝有StringList轉為XML節點。 XML節點顯示為:

    <List>
      <Entry>First String</Entry>
      <Entry>Second String</Entry>
      <Entry>Third String</Entry>
    </List>
    

    因為ListtoString方法可能有別的用途,所以不能使用。 可以為List添加一個工廠,當有轉為XML節點的請求時,一個Node對象就會自動返回。

    這里需要3個步驟:

    1. 從List中生成Node

    使用IAdapterFactory 來封裝轉換機制:

    import nu.xom.*;
    public class NodeListFactory implements IAdapterFactory {
      /** The supported types that we can adapt to */
      private static final Class[] types = {
        Node.class,
      };
      public Class[] getAdapterList() {
        return types;
      }
      /** The actual conversion to a 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. 注冊工廠到PlatformAdapterManager

    我們需要注冊工廠到適配器工廠,當我們向 List實例請求Node時, 它就會知道是使用我們注冊的工廠。 Platform為我們管理IAdapterManager ,而且注冊過程相當簡單:

    Platform.getAdapterManager().registerAdapters(
      new NodeListFactory(), List.class
    );
    

    上面的代碼要求平臺管理者關聯NodeListFactoryList。但我們要求List實例的適配器,它會調用這個工廠。根據我們對工廠的定義,會獲得一個Node對象。在Eclispe中,這一步必須在插件啟動的時候顯式的執行,要隱式執行可以通過 org.eclipse.core.runtime.adapters 擴展點。

    3. 向List要求Node

    這里是要求適配器返回一個 Node 對象:

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

    總結

    如果你要在運行時為已存在的類添加功能,只要定義一個能完成轉換功能的工廠,然后注冊工程到 PlatformAdapterManager就可以了. 這項功能可以用來為一個非UI組件注冊一個指定的UI組件,同時保持兩部分的完全分離。就像在org.rcpapps.rcpnews.uiorg.rcpapps.rcpnews 插件中的使用。在這些例子中, IPropertySource 在UI插件中,它需要與非UI插件的數據相關聯。當UI插件初始化時,它注冊IPropertySourcePlatform, 當數據對象在瀏覽器中被選中時,屬性視圖中就會顯示相應的屬性。

    很明顯, java.util.List不能擴展PlatformObject, 所以你不能指望例子中的代碼能夠編譯通過,你可以重新構造 List的子類來實現目的.繼承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();
      }
      // ...
    }
    

    本例中使用了XOM 來生成XML。

    from:
    http://www.javathink.org/bbs/read.php?tid-1469-page-e.html

    posted on 2006-07-19 21:49 CowNew開源團隊 閱讀(355) 評論(0)  編輯  收藏

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


    網站導航:
     
    主站蜘蛛池模板: 久久九九AV免费精品| 国产在线精品一区免费香蕉| 91麻豆国产自产在线观看亚洲| 久久精品无码专区免费东京热| 黄色a三级免费看| 日本亚洲免费无线码| 亚洲精品福利网泷泽萝拉| 亚洲综合色自拍一区| 国产成人免费网站在线观看| 色欲国产麻豆一精品一AV一免费 | 亚洲成人免费电影| 久草免费福利资源站| 精品亚洲永久免费精品| 久久成人18免费网站 | 全部免费国产潢色一级| 永久免费AV无码网站在线观看| 无码免费午夜福利片在线| 大学生一级特黄的免费大片视频| 男女做羞羞的事视频免费观看无遮挡 | 少妇人妻偷人精品免费视频| av片在线观看永久免费| 水蜜桃视频在线观看免费播放高清 | 97国产在线公开免费观看| 在线美女免费观看网站h| 成熟女人牲交片免费观看视频| 四虎永久免费观看| 国产精品怡红院永久免费| 黄色毛片免费网站| 国产大片免费天天看| 青青久久精品国产免费看| 国产日韩AV免费无码一区二区 | 免费人成在线观看播放国产 | 99久久国产免费-99久久国产免费| 久久综合AV免费观看| 国产亚洲视频在线播放| 亚洲综合自拍成人| 日日狠狠久久偷偷色综合免费| 99re6在线精品免费观看| 麻豆国产人免费人成免费视频| 精品国产亚洲男女在线线电影| 亚洲综合无码精品一区二区三区 |