专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » Java中IAdaptable是什么? »正文

Java中IAdaptable是什么?

来源: 发布时间:星期四, 2009年1月8日 浏览:5次 评论:0
  IAdaptable在Eclipse里是个非常重要接口对于Eclipse开发老手来说它就像异常处理和抽象类样寻常;但是对新手而言它却令人感到困惑和畏惧这篇文章将向你解释IAdaptable到底是什么以及它在Eclipse里起到作用

  类型转换

  Java是所谓强类型语言也就是说每个例子都对应个类型其实类型分为两种:声明类型和运行时类型(也分别被称为静态类型和动态类型)像Python这样弱类型语言常被称为无类型语言其实严格说来不是这样每个例子都对应个运行时类型只是你并不需要声明这点而已

  现在回到Java为了能够执行个类某个思路方法这个思路方法必须在声明类型中可见换句话说即使在运行时例子是某个子类型你也只能执行那些父类型里定义思路方法

List list = ArrayList;
list.add("data");    // 正确add是List里定义思路方法
list.ensureCapacity(4); // 不正确ensureCapacity只在ArrayList被定义


  如果定要执行特定类型思路方法我们必须先强制转换这个例子到正确类型对于上面例子我们可以将list转换为ArrayList(译注:原文In this , we can cast ArrayList to List怀疑是笔误)ArrayList实现了List接口你甚至可以在运行时通过instanceof关键字检验list是否为ArrayList个例子

  可扩展接口

  不幸个类可能并没有实现你需要接口这样就无法进行强制类型转换了原因有很多比如只在少数情况下才需要这个接口或者你需要接口是在另个不相关库里又或者接口是有了类以后才开发出来等等

  这时你就需要IAdaptable了可以把IAdaptable想象为个能够动态进行类型转换途径对比下面直接类型转换:

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


  换种方式我们可以这样做:

IAdaptable adaptable = ArrayList;//译注:这里ArrayList应该不是指java.util.ArrayList
List list = (List)adaptable.getAdapter(java.util.List.);


  这就是上面所说动态类型转换我们所做事情是试图把adaptable转换为个List例子

  那么当可以直接转换时候为什么要费这个力气通过getAdapter来转换呢?其实这种机制可以让我们将目标类转换为它并没有实现接口举个例子我们可能想把个HashMap当作List来用尽管这两个类性质并不相同可以这么做:

IAdaptable adaptable = HashMap;//译注:这里HashMap应该不是指java.util.HashMap
List list = (List)adaptable.getAdapter(java.util.List.);


  实现IAdaptable接口

  大部分IAdaptable实现是语句叠加比如我们现在要实现HashMapgetAdapter思路方法它看起来可能是这样:

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


  所做就是返回个适配器(adapter更确切说是个副本)而不是进行直接类型转换如果参数类型没有被支持惯例是返回null值(而非抛出异常)代表这个思路方法失败了因此这个思路方法时不应该假定它总是返回非null值

  PlatformObject

  当然如果你希望增加个新被支持adapter类型时必须编辑这个类才行(译注:在getAdapter里增加更多语句)这会比较辛苦而且既然你已经知道了这个类型何不直接修改接口声明呢?其实有很多原因使得你并不希望直接编辑这个类(例如更容易保持向下兼容性)也不想改变它类型(HashMap虽然不是个List但可以转换过去)

  Eclipse通过PlatformObject抽象类来解决以上问题它为你实现了IAdaptable接口Eclipse平台(Platform)提供了IAdapterManager个实现并且可以通过Platform.getAdapterManager访问到它把所有对getAdapter请求()委托给个名为IAdapterManager东西你可以将它想象为个巨大保存着类和adapter信息Map而PlatformObjectgetAdapter思路方法会查找这个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节点类型适配请求要管理工厂类需要以下 3个步骤:

  1、由List生成个Node我们把这个转换过程用IAdapterFactory包装起来:

import nu.xom.*;
public NodeListFactory implements IAdapterFactory {
 /**//* 可以转换到类型 */
 private final Class types = {
  Node.,
 };
 public Class getAdapterList {
   types;
 }
 /**//* 转换到Node功能代码 */
 public Object getAdapter(Object list, Class clazz) {
   (clazz Node. && list instanceof List) {
   Element root = Element("List");
   Iterator it = list.iterator;
   while(it.hasNext) {
    Element item = Element("Entry");
    item.appendChild(it.next.toString);
    root.appendChild(item);
   }
    root;
  } {
    null;
  }
 }
}


  2、把这个工厂类注册到PlatformAdapterManager这样当我们希望从List例子中获得个Node例子时就会找到我们工厂类注册个工厂类方式也很简单:

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


  这条语句将NodeListFactory关联到List类型当从List里请求adapter时PlatformAdapterManager会找到NodeListFactory在后者getAdapterList思路方法返回结果里包含了Node类所以它知道从List例子得到个Node例子是可行在Eclipse里这个注册步骤般是在plugin启动时完成但也可以通过org.eclipse.core.runtime.adapters扩展点来完成

  3、从List获得Node下面是例子代码:

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


  整理总结

  综上所述要在运行时为个已有类增加功能所要做只是定义个用来转换工厂类然后把它注册到PlatformAdapterManager即可这种方式在保持UI组件和非UI组件分离方面特别有用例如在org.rcpapps.rcps.ui和org.rcpapps.rcps这两个plugin里前者IPropertySource需要和后者数据对象(data object)相关联当前者化时它将IPropertySource注册到Platform当数据对象在导航器(navigator)里被选中时候属性视图里就会显示正确属性

  显然java.util.List并不是PlatformObject子类所以如果你希望能够编译这里所说例子必须建立个List子类型注意可以直接实现IAdaptable接口而非必须继承PlatformObject抽象类



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


  最后例子里生成XML部分使用了XOM类库.



标签:msn是什么
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: