在运行时更改实现/类

时间:2014-11-18 10:03:11

标签: java performance algorithm data-structures

我正在寻找在运行时更改对象(或变量)的具体类的(开源)程序(或算法)的真实世界示例。

Java中此类行为的示例可能类似于下面的代码片段。 这里,在频繁插入和/或删除的上下文中表现良好的LinkedList被更改为ArrayList,在随机访问和迭代的上下文中表现良好。

List myList = new LinkedList(); 
/* Lots of inserts */
...
myList = new ArrayList( myList ); // 'change' into different class
/* Lots of iteration */
...

上面的Java示例在LinkedListArrayList之间进行了更改 表现。

但是,任何语言的示例,任何数据结构,使用任何技术*,以及出于任何原因都是受欢迎的。

*技术:简单简单,如上例所示,或者 在SmallTalk中使用become:,在Python中使用__class__,或者......

4 个答案:

答案 0 :(得分:2)

您可能想要检查Smalltalk中become方法的用例。该方法在运行时更改实例的类(或更改对实例的所有引用以引用不同的实例)

成为常用于增长/缩小集合,例如带有更多桶的字典,带有更大缓冲区的ByteArray等。可以从SmallInteger转换为BigIntegers(前者的大小有限,后者不是,但速度要慢得多),程序员甚至不会注意到(这是只有当你有可变整数时才合理,因此在Smalltalk中这不是怎么做的。但它可能是:)

另一种情况可能是将序列化表单中的实例加载回正在运行的系统,并将其类更新为最新版本。

答案 1 :(得分:2)

是的,请查看Smalltalk中的#become(例如麻省理工学院授权的Pharo.org)。

除了已经给出的例子之外,#become例如是有用的 你使用代理。想想ORM框架中的代理对象,比如 Glorp,您首先拥有代理以及何时需要真正的完整对象 它可以从数据库加载,很容易切换所有引用。

另一个例子是Pharo的Fuel框架。

答案 2 :(得分:1)

不知道这是否相关,但是间谍(部分嘲笑)的使用也符合你的描述(见http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/Spy.html):

一个例子:

Person person = new Person();
person = spy(person);
doReturn("dominiek").when(person).getName();

在幕后创建一个子类,并根据用户'更改类的行为。行为声明。

答案 3 :(得分:1)

我只是在(Python) NLTK来源中遇到了这个实例。 LazyCorpusLoader(用于从磁盘加载数据集的对象)"变形"进入数据集本身。这是链接源代码的相关部分(创建数据集对象然后成为它):

    corpus = self.__reader_cls(root, *self.__args, **self.__kwargs)

    # This is where the magic happens!  Transform ourselves into
    # the corpus by modifying our own __dict__ and __class__ to
    # match that of the corpus.

    args, kwargs  = self.__args, self.__kwargs
    name, reader_cls = self.__name, self.__reader_cls

    self.__dict__ = corpus.__dict__
    self.__class__ = corpus.__class__

以下是此技术的基本原理(在同一文件的标题中):

  

LazyCorpusLoader是一个代理对象,用于代表a   语料库加载前的语料库对象。这允许NLTK   为每个语料库创建一个对象,但推迟相关的成本   加载这些语料库直到他们第一次   实际访问过。

因此,在这种情况下,在运行时更改类的目的是来模拟延迟评估

(编辑:由于我从NLTK源(Apache 2.0许可证)逐字引用,这里是许可证本身的强制性链接:http://www.apache.org/licenses/LICENSE-2.0